Add 'deleteRealmIfMigrationNeeded' to configuration to delete a Realm if migration needed (#502)
This commit is contained in:
parent
199210eb68
commit
670f7507f2
|
@ -5,6 +5,7 @@ X.Y.Z Release notes
|
|||
|
||||
### Enhancements
|
||||
* Added aggregate functions `min()`, `max()`, `sum()`, and `avg()` to `Realm.Results` and `Realm.List` (#807).
|
||||
* Added `deleteRealmIfMigrationNeeded` to configuration to delete a Realm if migration needed (#502).
|
||||
|
||||
### Bug fixes
|
||||
* Fixed port conflict between RN >= 0.48 inspector proxy and RPC server used for Chrome debugging (#1294).
|
||||
|
|
|
@ -296,6 +296,8 @@ Realm.defaultPath;
|
|||
* - `validate_ssl` - Indicating if SSL certificates must be validated
|
||||
* - `ssl_trust_certificate_path` - A path where to find trusted SSL certificates
|
||||
* The `error` callback can take up to four optional arguments: `message`, `isFatal`, `category`, and `code`.
|
||||
* @property {boolean} [deleteRealmIfMigrationNeeded=false] - Specifies if this Realm should be deleted
|
||||
* if a migration is needed.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,6 +84,7 @@ declare namespace Realm {
|
|||
schema?: ObjectClass[] | ObjectSchema[];
|
||||
schemaVersion?: number;
|
||||
sync?: Realm.Sync.SyncConfiguration;
|
||||
deleteRealmIfMigrationNeeded?: boolean;
|
||||
}
|
||||
|
||||
// object props type
|
||||
|
|
|
@ -394,6 +394,16 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
|||
config.schema_mode = SchemaMode::ReadOnly;
|
||||
}
|
||||
|
||||
static const String delete_realm_if_migration_needed_string = "deleteRealmIfMigrationNeeded";
|
||||
ValueType delete_realm_if_migration_needed_value = Object::get_property(ctx, object, delete_realm_if_migration_needed_string);
|
||||
if (!Value::is_undefined(ctx, delete_realm_if_migration_needed_value) && Value::validated_to_boolean(ctx, delete_realm_if_migration_needed_value, "deleteRealmIfMigrationNeeded")) {
|
||||
if (config.schema_mode == SchemaMode::ReadOnly) {
|
||||
throw std::invalid_argument("Cannot set 'deleteRealmIfMigrationNeeded' when 'readOnly' is set.");
|
||||
}
|
||||
|
||||
config.schema_mode = SchemaMode::ResetFile;
|
||||
}
|
||||
|
||||
static const String schema_string = "schema";
|
||||
ValueType schema_value = Object::get_property(ctx, object, schema_string);
|
||||
if (!Value::is_undefined(ctx, schema_value)) {
|
||||
|
@ -437,6 +447,11 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
|||
ValueType migration_value = Object::get_property(ctx, object, migration_string);
|
||||
if (!Value::is_undefined(ctx, migration_value)) {
|
||||
FunctionType migration_function = Value::validated_to_function(ctx, migration_value, "migration");
|
||||
|
||||
if (config.schema_mode == SchemaMode::ResetFile) {
|
||||
throw std::invalid_argument("Cannot include 'migration' when 'deleteRealmIfMigrationNeeded' is set.");
|
||||
}
|
||||
|
||||
config.migration_function = [=](SharedRealm old_realm, SharedRealm realm, realm::Schema&) {
|
||||
auto old_realm_ptr = new SharedRealm(old_realm);
|
||||
auto realm_ptr = new SharedRealm(realm);
|
||||
|
|
|
@ -1025,5 +1025,137 @@ module.exports = {
|
|||
const realm2 = new Realm(config);
|
||||
TestCase.assertEqual(realm2.objects('TestObject').length, 0);
|
||||
realm.close();
|
||||
}
|
||||
},
|
||||
|
||||
testRealmDeleteRealmIfMigrationNeededVersionChanged: function() {
|
||||
const schema = [{
|
||||
name: 'TestObject',
|
||||
properties: {
|
||||
prop0: 'string',
|
||||
prop1: 'int',
|
||||
}
|
||||
}];
|
||||
|
||||
var realm = new Realm({schema: schema});
|
||||
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', ['stringValue', 1]);
|
||||
});
|
||||
|
||||
realm.close();
|
||||
|
||||
|
||||
realm = new Realm({schema: schema, deleteRealmIfMigrationNeeded: true, schemaVersion: 1, migration: undefined });
|
||||
|
||||
// object should be gone as Realm should get deleted
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 0);
|
||||
|
||||
// create a new object
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', ['stringValue', 1]);
|
||||
});
|
||||
|
||||
realm.close();
|
||||
|
||||
var migrationWasCalled = false;
|
||||
realm = new Realm({schema: schema, deleteRealmIfMigrationNeeded: false, schemaVersion: 2, migration: function(oldRealm, newRealm) {
|
||||
migrationWasCalled = true;
|
||||
}});
|
||||
|
||||
// migration function should get called as deleteRealmIfMigrationNeeded is false
|
||||
TestCase.assertEqual(migrationWasCalled, true);
|
||||
|
||||
// object should be there because Realm shouldn't get deleted
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||
realm.close();
|
||||
},
|
||||
|
||||
testRealmDeleteRealmIfMigrationNeededSchemaChanged: function() {
|
||||
const schema = [{
|
||||
name: 'TestObject',
|
||||
properties: {
|
||||
prop0: 'string',
|
||||
prop1: 'int',
|
||||
}
|
||||
}];
|
||||
|
||||
const schema1 = [{
|
||||
name: 'TestObject',
|
||||
properties: {
|
||||
prop0: 'string',
|
||||
prop1: 'int',
|
||||
prop2: 'float',
|
||||
}
|
||||
}];
|
||||
|
||||
const schema2 = [{
|
||||
name: 'TestObject',
|
||||
properties: {
|
||||
prop0: 'string',
|
||||
prop1: 'int',
|
||||
prop2: 'float',
|
||||
prop3: 'double'
|
||||
}
|
||||
}];
|
||||
|
||||
var realm = new Realm({schema: schema});
|
||||
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', {prop0: 'stringValue', prop1: 1});
|
||||
});
|
||||
|
||||
realm.close();
|
||||
|
||||
|
||||
// change schema
|
||||
realm = new Realm({schema: schema1, deleteRealmIfMigrationNeeded: true, migration: undefined});
|
||||
|
||||
// object should be gone as Realm should get deleted
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 0);
|
||||
|
||||
// create a new object
|
||||
realm.write(function() {
|
||||
realm.create('TestObject', {prop0: 'stringValue', prop1: 1, prop2: 1.0});
|
||||
});
|
||||
|
||||
realm.close();
|
||||
|
||||
|
||||
TestCase.assertThrows(function(e) {
|
||||
// updating schema without changing schemaVersion OR setting deleteRealmIfMigrationNeeded = true should raise an error
|
||||
new Realm({schema: schema2, deleteRealmIfMigrationNeeded: false, migration: function(oldRealm, newRealm) {}});
|
||||
});
|
||||
|
||||
var migrationWasCalled = false;
|
||||
|
||||
// change schema again, but increment schemaVersion
|
||||
realm = new Realm({schema: schema2, deleteRealmIfMigrationNeeded: false, schemaVersion: 1, migration: function(oldRealm, newRealm) {
|
||||
migrationWasCalled = true;
|
||||
}});
|
||||
|
||||
// migration function should get called as deleteRealmIfMigrationNeeded is false
|
||||
TestCase.assertEqual(migrationWasCalled, true);
|
||||
|
||||
// object should be there because Realm shouldn't get deleted
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||
realm.close();
|
||||
},
|
||||
|
||||
testRealmDeleteRealmIfMigrationNeededIncompatibleConfig: function() {
|
||||
const schema = [{
|
||||
name: 'TestObject',
|
||||
properties: {
|
||||
prop0: 'string',
|
||||
prop1: 'int',
|
||||
}
|
||||
}];
|
||||
|
||||
TestCase.assertThrows(function() {
|
||||
new Realm({schema: schema, deleteRealmIfMigrationNeeded: true, readOnly: true});
|
||||
}, "Cannot set 'deleteRealmIfMigrationNeeded' when 'readOnly' is set.")
|
||||
|
||||
TestCase.assertThrows(function() {
|
||||
new Realm({schema: schema, deleteRealmIfMigrationNeeded: true, migration: function(oldRealm, newRealm) {}});
|
||||
}, "Cannot include 'migration' when 'deleteRealmIfMigrationNeeded' is set.")
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue