From 495355f3fe3e8edc036fe51c49d166a6a23687f8 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 6 Jun 2018 15:58:52 -0700 Subject: [PATCH 1/3] Expose both newModifications and oldModifications on change events --- CHANGELOG.md | 2 +- docs/collection.js | 9 ++++++--- lib/index.d.ts | 2 ++ src/js_collection.hpp | 31 ++++++++++++++++--------------- tests/js/results-tests.js | 7 +++++++ 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc2d6048..860d457b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * 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. ### 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. diff --git a/docs/collection.js b/docs/collection.js index 53e5e7ed..c8de7cb1 100644 --- a/docs/collection.js +++ b/docs/collection.js @@ -427,9 +427,12 @@ 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`: 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. 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. * @throws {Error} If `callback` is not a function. diff --git a/lib/index.d.ts b/lib/index.d.ts index a810d858..11ba8602 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -140,6 +140,8 @@ declare namespace Realm { insertions: number[]; deletions: number[]; modifications: number[]; + newModifications: number[]; + oldModifications: number[]; } type CollectionChangeCallback = (collection: Collection, change: CollectionChangeSet) => void; diff --git a/src/js_collection.hpp b/src/js_collection.hpp index a83db75f..f75e2823 100644 --- a/src/js_collection.hpp +++ b/src/js_collection.hpp @@ -50,27 +50,28 @@ template typename T::Value CollectionClass::create_collection_change_set(ContextType ctx, const CollectionChangeSet &change_set) { ObjectType object = Object::create_empty(ctx); - std::vector deletions, insertions, modifications; + std::vector 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::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; } diff --git a/tests/js/results-tests.js b/tests/js/results-tests.js index adb345bf..09b234c7 100644 --- a/tests/js/results-tests.js +++ b/tests/js/results-tests.js @@ -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 }); }); }); From 1e5e59d3c035f34e570c31d3f36d6198248dc169 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Thu, 7 Jun 2018 11:23:59 +0200 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 860d457b..518773af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * None. ### Enhancements -* 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. +* 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. From 4dc4bac37e14536bafb7d05ee3ce7e455695b36c Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Thu, 7 Jun 2018 11:25:38 +0200 Subject: [PATCH 3/3] Update collection.js --- docs/collection.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/docs/collection.js b/docs/collection.js index c8de7cb1..07c92472 100644 --- a/docs/collection.js +++ b/docs/collection.js @@ -431,21 +431,15 @@ class Collection { * 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. 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. + * `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) {}