Merge `master` into `2.0.x` (#1377)
* Add 'deleteRealmIfMigrationNeeded' to configuration to delete a Realm if migration needed (#502) * Minor update due to changes in objec store
This commit is contained in:
parent
1cabee36df
commit
19d05c2021
|
@ -78,6 +78,7 @@ X.Y.Z-rc? Release notes (DATE)
|
|||
### Enhancements
|
||||
* Add a callback function used to verify SSL certificates in the sync config.
|
||||
* 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).
|
||||
|
|
|
@ -282,6 +282,8 @@ Realm.defaultPath;
|
|||
* This function takes two arguments:
|
||||
* - `oldRealm` - The Realm before migration is performed.
|
||||
* - `newRealm` - The Realm that uses the latest `schema`, which should be modified as necessary.
|
||||
* @property {boolean} [deleteRealmIfMigrationNeeded=false] - Specifies if this Realm should be deleted
|
||||
* if a migration is needed.
|
||||
* @property {callback(number, number)} [shouldCompactOnLaunch] - The function called when opening
|
||||
* a Realm for the first time during the life of a process to determine if it should be compacted
|
||||
* before being returned to the user. The function takes two arguments:
|
||||
|
|
|
@ -84,6 +84,7 @@ declare namespace Realm {
|
|||
schema?: ObjectClass[] | ObjectSchema[];
|
||||
schemaVersion?: number;
|
||||
sync?: Realm.Sync.SyncConfiguration;
|
||||
deleteRealmIfMigrationNeeded?: boolean;
|
||||
}
|
||||
|
||||
// object props type
|
||||
|
|
|
@ -422,6 +422,16 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
|||
config.schema_mode = SchemaMode::Immutable;
|
||||
}
|
||||
|
||||
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::Immutable) {
|
||||
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)) {
|
||||
|
@ -465,6 +475,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);
|
||||
|
|
|
@ -1041,5 +1041,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