Merge pull request #1849 from realm/tg/new-modifications

Expose both newModifications and oldModifications on change events
This commit is contained in:
Kenneth Geisshirt 2018-06-07 11:55:23 +02:00 committed by GitHub
commit d8e41fa469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 28 deletions

View File

@ -10,7 +10,7 @@ X.Y.Z Release notes
* None.
### Enhancements
* None.
* Add the `oldModifications` and `newModifications` properties to the listener change objects, which report the indices that changed in the collection both before and after the changes being notified for. The `modifications` property is kept as an alias for `oldModifications` but might be removed in a future version.
### Bug fixes
* [Sync] Fixed a bug which crash query-based Realms. A bug in gcc's optimizer will generate code which in some case will lead to a memory violation and eventually a segmentation fault.

View File

@ -427,22 +427,19 @@ class Collection {
* @param {function(collection, changes)} callback - A function to be called when changes occur.
* The callback function is called with two arguments:
* - `collection`: the collection instance that changed,
* - `changes`: a dictionary with keys `insertions`, `modifications` and `deletions`,
* each containing a list of indices that were inserted, updated or deleted respectively. If
* partial sync is enabled, an additional key `partial_sync` is added.
* - `changes.partial_sync`: `error` indicates if an error has occurred, `old_state` is the previous
* state, and `new_state` is the current state.
* - `changes`: a dictionary with keys `insertions`, `newModifications`, `oldModifications`
* and `deletions`, each containing a list of indices in the collection that were
* inserted, updated or deleted respectively. `deletions` and `oldModifications` are
* indices into the collection before the change happened, while `insertions` and
* `newModifications` are indices into the new version of the collection.
* @throws {Error} If `callback` is not a function.
* @example
* wines.addListener((collection, changes) => {
* // collection === wines
* if (changes.partial_sync.new_state == Realm.Sync.SubscriptionState.Initialized) {
* console.log('Our subset is ready');
* console.log(`${changes.insertions.length} insertions`);
* console.log(`${changes.modifications.length} modifications`);
* console.log(`${changes.deletions.length} deletions`);
* console.log(`new size of collection: ${collection.length}`);
* }
* console.log(`${changes.insertions.length} insertions`);
* console.log(`${changes.modifications.length} modifications`);
* console.log(`${changes.deletions.length} deletions`);
* console.log(`new size of collection: ${collection.length}`);
* });
*/
addListener(callback) {}

2
lib/index.d.ts vendored
View File

@ -140,6 +140,8 @@ declare namespace Realm {
insertions: number[];
deletions: number[];
modifications: number[];
newModifications: number[];
oldModifications: number[];
}
type CollectionChangeCallback<T> = (collection: Collection<T>, change: CollectionChangeSet) => void;

View File

@ -50,27 +50,28 @@ template<typename T>
typename T::Value CollectionClass<T>::create_collection_change_set(ContextType ctx, const CollectionChangeSet &change_set)
{
ObjectType object = Object::create_empty(ctx);
std::vector<ValueType> deletions, insertions, modifications;
std::vector<ValueType> scratch;
auto make_array = [&](realm::IndexSet const& index_set) {
scratch.clear();
scratch.reserve(index_set.count());
for (auto index : index_set.as_indexes()) {
scratch.push_back(Value::from_number(ctx, index));
}
return Object::create_array(ctx, scratch);
};
if (change_set.deletions.count() == std::numeric_limits<size_t>::max()) {
deletions.push_back(Value::from_null(ctx));
Object::set_property(ctx, object, "deletions", Object::create_array(ctx, {Value::from_null(ctx)}));
}
else {
for (auto index : change_set.deletions.as_indexes()) {
deletions.push_back(Value::from_number(ctx, index));
}
Object::set_property(ctx, object, "deletions", make_array(change_set.deletions));
}
Object::set_property(ctx, object, "deletions", Object::create_array(ctx, deletions));
Object::set_property(ctx, object, "insertions", make_array(change_set.insertions));
Object::set_property(ctx, object, "newModifications", make_array(change_set.modifications_new));
for (auto index : change_set.insertions.as_indexes()) {
insertions.push_back(Value::from_number(ctx, index));
}
Object::set_property(ctx, object, "insertions", Object::create_array(ctx, insertions));
for (auto index : change_set.modifications.as_indexes()) {
modifications.push_back(Value::from_number(ctx, index));
}
Object::set_property(ctx, object, "modifications", Object::create_array(ctx, modifications));
auto old_modifications = make_array(change_set.modifications);
Object::set_property(ctx, object, "modifications", old_modifications);
Object::set_property(ctx, object, "oldModifications", old_modifications);
return object;
}

View File

@ -452,10 +452,16 @@ module.exports = {
if (first) {
TestCase.assertEqual(testObjects.length, 3);
TestCase.assertEqual(changes.insertions.length, 0);
TestCase.assertEqual(changes.modifications.length, 0);
TestCase.assertEqual(changes.newModifications.length, 0);
TestCase.assertEqual(changes.oldModifications.length, 0);
}
else {
TestCase.assertEqual(testObjects.length, 4);
TestCase.assertEqual(changes.insertions.length, 1);
TestCase.assertEqual(changes.modifications.length, 1);
TestCase.assertEqual(changes.newModifications.length, 1);
TestCase.assertEqual(changes.oldModifications.length, 1);
}
first = false;
resolve();
@ -464,6 +470,7 @@ module.exports = {
return new Promise((r, _reject) => {
resolve = r;
realm.write(() => {
realm.objects('TestObject')[0].doubleCol = 5;
realm.create('TestObject', { doubleCol: 1 });
});
});