Skip to content

Commit

Permalink
Expose NewModifiedIndices (#1752)
Browse files Browse the repository at this point in the history
* Expose NewModifiedIndices

* Changelog
  • Loading branch information
nirinchev committed Jun 22, 2018
1 parent 5d6a7f5 commit 7556567
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
------------------

### Enhancements
- Exposed a `ChangeSet.NewModifiedIndices` collection that contains information about the
indices of the objects that changed in the new version of the collection (i.e. after
accounting for the insertions and deletions).

### Bug fixes
- `WriteAsync` will no longer perform a synchronous `Refresh` on the main thread. ([#1729](https://github.com/realm/realm-dotnet/pull/1729))
Expand Down
1 change: 1 addition & 0 deletions Realm/Realm/Handles/NotifiableObjectHandleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal struct CollectionChangeSet
public MarshaledVector<IntPtr> Deletions;
public MarshaledVector<IntPtr> Insertions;
public MarshaledVector<IntPtr> Modifications;
public MarshaledVector<IntPtr> Modifications_New;

[StructLayout(LayoutKind.Sequential)]
public struct Move
Expand Down
13 changes: 11 additions & 2 deletions Realm/Realm/Linq/IRealmCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,21 @@ public class ChangeSet
public int[] InsertedIndices { get; }

/// <summary>
/// Gets the indices in the new version of the <see cref="IRealmCollection{T}"/> which were modified.
/// Gets the indices in the *old* version of the <see cref="IRealmCollection{T}"/> which were modified.
/// This means that either the property of an object at that index was modified or the property of
/// of an object it's related to has changed.
/// </summary>
/// <value>An array, containing the indices of the modified objects.</value>
public int[] ModifiedIndices { get; }

/// <summary>
/// Gets the indices in the *new* version of the <see cref="IRealmCollection{T}"/> which were modified.
/// Conceptually, it contains the same entries as <see cref="ModifiedIndices"/> but after the insertions
/// and deletions have been accounted for.
/// </summary>
/// <value>An array, containing the indices of the modified objects.</value>
public int[] NewModifiedIndices { get; }

/// <summary>
/// Gets the indices of objects in the previous version of the <see cref="IRealmCollection{T}"/> which have been removed from this one.
/// </summary>
Expand All @@ -58,10 +66,11 @@ public class ChangeSet
/// <value>An array of <see cref="Move"/> structs, indicating the source and the destination index of the moved row.</value>
public Move[] Moves { get; }

internal ChangeSet(int[] insertedIndices, int[] modifiedIndices, int[] deletedIndices, Move[] moves)
internal ChangeSet(int[] insertedIndices, int[] modifiedIndices, int[] newModifiedIndices, int[] deletedIndices, Move[] moves)
{
InsertedIndices = insertedIndices;
ModifiedIndices = modifiedIndices;
NewModifiedIndices = newModifiedIndices;
DeletedIndices = deletedIndices;
Moves = moves;
}
Expand Down
1 change: 1 addition & 0 deletions Realm/Realm/RealmCollectionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ void NotificationsHelper.INotifiable.NotifyCallbacks(NotifiableObjectHandleBase.
changeset = new ChangeSet(
insertedIndices: actualChanges.Insertions.AsEnumerable().Select(i => (int)i).ToArray(),
modifiedIndices: actualChanges.Modifications.AsEnumerable().Select(i => (int)i).ToArray(),
newModifiedIndices: actualChanges.Modifications_New.AsEnumerable().Select(i => (int)i).ToArray(),
deletedIndices: actualChanges.Deletions.AsEnumerable().Select(i => (int)i).ToArray(),
moves: actualChanges.Moves.AsEnumerable().Select(m => new ChangeSet.Move((int)m.From, (int)m.To)).ToArray());
}
Expand Down
40 changes: 40 additions & 0 deletions Tests/Tests.Shared/NotificationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,46 @@ void helper(IRealmCollection<Person> _, ChangeSet changes, Exception __)
});
}

[Test]
public void ModifiedIndices_ReportCorrectlyForOldAndNewVersions()
{
ChangeSet changes = null;
void cb(IRealmCollection<IntPrimaryKeyWithValueObject> s, ChangeSet c, Exception e) => changes = c;

var toDelete = new IntPrimaryKeyWithValueObject { Id = 1 };
var toModify = new IntPrimaryKeyWithValueObject { Id = 2 };

_realm.Write(() =>
{
_realm.Add(toDelete);
_realm.Add(toModify);
});

var query = _realm.All<IntPrimaryKeyWithValueObject>().OrderBy(i => i.Id);
using (query.SubscribeForNotifications(cb))
{
Assert.That(query.ElementAt(0).Equals(toDelete));
Assert.That(query.ElementAt(1).Equals(toModify));

_realm.Write(() =>
{
_realm.Remove(toDelete);
toModify.StringValue = "newValue";
});

_realm.Refresh();
Assert.That(changes, Is.Not.Null);
Assert.That(changes.DeletedIndices, Is.EquivalentTo(new int[] { 0 }));

// Modified should be in the old collection
Assert.That(changes.ModifiedIndices, Is.EquivalentTo(new int[] { 1 }));

// NewModified should be in the new collection that is just 1 element
Assert.That(changes.NewModifiedIndices, Is.EquivalentTo(new int[] { 0 }));
Assert.That(query.ElementAt(changes.NewModifiedIndices[0]).Equals(toModify));
}
}

public static IEnumerable<TestCaseData> CollectionChangedTestCases()
{
yield return new TestCaseData(new int[] { }, NotifyCollectionChangedAction.Add, new int[] { 1 }, 0);
Expand Down
5 changes: 4 additions & 1 deletion wrappers/src/notifications_cs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ namespace realm {
MarshallableIndexSet deletions;
MarshallableIndexSet insertions;
MarshallableIndexSet modifications;

MarshallableIndexSet modifications_new;

struct {
CollectionChangeSet::Move* moves;
size_t count;
Expand Down Expand Up @@ -88,6 +89,7 @@ namespace realm {
auto deletions = get_indexes_vector(changes.deletions);
auto insertions = get_indexes_vector(changes.insertions);
auto modifications = get_indexes_vector(changes.modifications);
auto modifications_new = get_indexes_vector(changes.modifications_new);

std::vector<size_t> properties;

Expand All @@ -101,6 +103,7 @@ namespace realm {
{ deletions.data(), deletions.size() },
{ insertions.data(), insertions.size() },
{ modifications.data(), modifications.size() },
{ modifications_new.data(), modifications_new.size() },
{ changes.moves.data(), changes.moves.size() },
{ properties.data(), properties.size() }
};
Expand Down

0 comments on commit 7556567

Please sign in to comment.