Merge pull request #1290 from realm/ap/delete_model
Add Realm.deleteModel API (#573)
This commit is contained in:
commit
95ea9bd38a
|
@ -8,6 +8,7 @@ X.Y.Z Release notes
|
||||||
* Added Progress API `realm.syncSession.addProgressNotification` and `realm.syncSession.removeProgressNotification`
|
* Added Progress API `realm.syncSession.addProgressNotification` and `realm.syncSession.removeProgressNotification`
|
||||||
* Added additional parameter for `Realm.open` and `Realm.openAsync` for download progress notifications
|
* Added additional parameter for `Realm.open` and `Realm.openAsync` for download progress notifications
|
||||||
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
||||||
|
* Added `Realm.deleteModel` for deleting a Realm model in a migration (#573).
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
* Adding missing TypeScript declation (#1283).
|
* Adding missing TypeScript declation (#1283).
|
||||||
|
|
|
@ -132,6 +132,12 @@ class Realm {
|
||||||
*/
|
*/
|
||||||
delete(object) {}
|
delete(object) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a Realm model, including all of its objects.
|
||||||
|
* @param {string} name - the model name
|
||||||
|
*/
|
||||||
|
deleteModel(name) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **WARNING:** This will delete **all** objects in the Realm!
|
* **WARNING:** This will delete **all** objects in the Realm!
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -131,6 +131,7 @@ util.createMethods(Realm.prototype, objectTypes.REALM, [
|
||||||
// Mutating methods:
|
// Mutating methods:
|
||||||
util.createMethods(Realm.prototype, objectTypes.REALM, [
|
util.createMethods(Realm.prototype, objectTypes.REALM, [
|
||||||
'delete',
|
'delete',
|
||||||
|
'deleteModel',
|
||||||
'deleteAll',
|
'deleteAll',
|
||||||
'write',
|
'write',
|
||||||
'compact',
|
'compact',
|
||||||
|
|
|
@ -484,6 +484,11 @@ declare class Realm {
|
||||||
*/
|
*/
|
||||||
delete(object: Realm.Object | Realm.Object[] | Realm.List<any> | Realm.Results<any> | any): void;
|
delete(object: Realm.Object | Realm.Object[] | Realm.List<any> | Realm.Results<any> | any): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
deleteModel(name: string): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -180,7 +180,7 @@ public:
|
||||||
static void remove_all_listeners(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
static void remove_all_listeners(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||||
static void close(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
static void close(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||||
static void compact(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
static void compact(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||||
|
static void delete_model(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
static void get_empty(ContextType, ObjectType, ReturnValue &);
|
static void get_empty(ContextType, ObjectType, ReturnValue &);
|
||||||
|
@ -235,6 +235,7 @@ public:
|
||||||
{"removeAllListeners", wrap<remove_all_listeners>},
|
{"removeAllListeners", wrap<remove_all_listeners>},
|
||||||
{"close", wrap<close>},
|
{"close", wrap<close>},
|
||||||
{"compact", wrap<compact>},
|
{"compact", wrap<compact>},
|
||||||
|
{"deleteModel", wrap<delete_model>},
|
||||||
};
|
};
|
||||||
|
|
||||||
PropertyMap<T> const properties = {
|
PropertyMap<T> const properties = {
|
||||||
|
@ -559,6 +560,17 @@ void RealmClass<T>::delete_file(ContextType ctx, FunctionType, ObjectType this_o
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void RealmClass<T>::delete_model(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||||
|
validate_argument_count(argc, 1);
|
||||||
|
ValueType value = arguments[0];
|
||||||
|
|
||||||
|
SharedRealm& realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||||
|
|
||||||
|
std::string model_name = Value::validated_to_string(ctx, value, "deleteModel");
|
||||||
|
ObjectStore::delete_data_for_object(realm->read_group(), model_name);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void RealmClass<T>::get_default_path(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
void RealmClass<T>::get_default_path(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
||||||
return_value.set(realm::js::default_path());
|
return_value.set(realm::js::default_path());
|
||||||
|
|
|
@ -158,4 +158,170 @@ module.exports = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
testDeleteModelMigration: 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: [], schemaVersion: 1});
|
||||||
|
TestCase.assertEqual(realm.schema.length, 0); // no models
|
||||||
|
realm.close(); // this won't delete the model
|
||||||
|
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 2});
|
||||||
|
TestCase.assertEqual(realm.objects('TestObject').length, 1); // the model objects are still there
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
// now delete the model explicitly, which should delete the objects too
|
||||||
|
realm = new Realm({schema: [], schemaVersion: 3, migration: function(oldRealm, newRealm) {
|
||||||
|
newRealm.deleteModel('TestObject');
|
||||||
|
}});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.schema.length, 0); // no models
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 4});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.objects('TestObject').length, 0);
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
testDeleteModelInSchema: 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();
|
||||||
|
|
||||||
|
|
||||||
|
// now delete the model explicitly, but it should remain as it's still in the schema
|
||||||
|
// only the rows should get deleted
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 1, migration: function(oldRealm, newRealm) {
|
||||||
|
newRealm.deleteModel('TestObject');
|
||||||
|
}});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.schema.length, 1); // model should remain
|
||||||
|
TestCase.assertEqual(realm.objects('TestObject').length, 0); // objects should be gone
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 2});
|
||||||
|
TestCase.assertEqual(realm.objects('TestObject').length, 0);
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
testDeleteModelIgnoreNotExisting: 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();
|
||||||
|
|
||||||
|
// non-existing models should be ignore on delete
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 1, migration: function(oldRealm, newRealm) {
|
||||||
|
newRealm.deleteModel('NonExistingModel');
|
||||||
|
}});
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
realm = new Realm({schema: schema, schemaVersion: 2});
|
||||||
|
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
testDeleteModelWithRelationship: function() {
|
||||||
|
const ShipSchema = {
|
||||||
|
name: 'Ship',
|
||||||
|
properties: {
|
||||||
|
ship_name: 'string',
|
||||||
|
captain: 'Captain'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const CaptainSchema = {
|
||||||
|
name: 'Captain',
|
||||||
|
properties: {
|
||||||
|
captain_name: 'string',
|
||||||
|
ships: { type: 'linkingObjects', objectType: 'Ship', property: 'captain' }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var realm = new Realm({schema: [ShipSchema, CaptainSchema]});
|
||||||
|
|
||||||
|
realm.write(function() {
|
||||||
|
realm.create('Ship', {
|
||||||
|
ship_name: 'My Ship',
|
||||||
|
captain: {
|
||||||
|
captain_name: 'John Doe'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.objects('Captain').length, 1);
|
||||||
|
TestCase.assertEqual(realm.objects('Ship').length, 1);
|
||||||
|
TestCase.assertEqual(realm.objects('Ship')[0].captain.captain_name, "John Doe");
|
||||||
|
TestCase.assertEqual(realm.objects('Captain')[0].ships[0].ship_name, "My Ship");
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
realm = new Realm({schema: [ShipSchema, CaptainSchema], schemaVersion: 1, migration: function(oldRealm, newRealm) {
|
||||||
|
TestCase.assertThrows(function(e) {
|
||||||
|
// deleting a model which is target of linkingObjects results in an exception
|
||||||
|
newRealm.deleteModel('Captain');
|
||||||
|
console.log(e);
|
||||||
|
}, "Table is target of cross-table link columns");
|
||||||
|
}});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.objects('Captain').length, 1);
|
||||||
|
TestCase.assertEqual(realm.objects('Ship').length, 1);
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
realm = new Realm({schema: [ShipSchema, CaptainSchema], schemaVersion: 2, migration: function(oldRealm, newRealm) {
|
||||||
|
// deleting a model which isn't target of linkingObjects works fine
|
||||||
|
newRealm.deleteModel('Ship');
|
||||||
|
}});
|
||||||
|
|
||||||
|
TestCase.assertEqual(realm.objects('Captain').length, 1);
|
||||||
|
TestCase.assertEqual(realm.objects('Ship').length, 0);
|
||||||
|
TestCase.assertEqual(realm.objects('Captain')[0].ships.length, 0);
|
||||||
|
|
||||||
|
realm.close();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue