Skip to content

Commit

Permalink
Fixing MapDeleted when using scoped indexers
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienros committed Oct 11, 2018
1 parent 4350a84 commit db4ec61
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/YesSql.Abstractions/Indexes/DescribeFor.cs
Expand Up @@ -110,7 +110,7 @@ public void Delete(Func<TIndex, IEnumerable<TIndex>, TIndex> delete = null)

Func<object, Task<IEnumerable<IIndex>>> IDescribeFor.GetMap()
{
return async x => (await _map((T)x)).Cast<IIndex>();
return async x => (await _map((T)x) ?? Enumerable.Empty<TIndex>()).Cast<IIndex>();
}

Func<IGrouping<object, IIndex>, IIndex> IDescribeFor.GetReduce()
Expand Down
85 changes: 44 additions & 41 deletions src/YesSql.Core/Session.cs
@@ -1,6 +1,5 @@
using Dapper;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
Expand Down Expand Up @@ -84,14 +83,8 @@ public void Save(object entity)
}

// is it a new object?
if (_identityMap.TryGetDocumentId(entity, out int id))
if (_identityMap.TryGetDocumentId(entity, out var id))
{
// already being updated?
if (_updated.Contains(entity))
{
return;
}

_updated.Add(entity);
return;
}
Expand Down Expand Up @@ -186,7 +179,7 @@ private async Task UpdateEntityAsync(object entity)
}

// Reload to get the old map
if (!_identityMap.TryGetDocumentId(entity, out int id))
if (!_identityMap.TryGetDocumentId(entity, out var id))
{
throw new InvalidOperationException("The object to update was not found in identity map.");
}
Expand Down Expand Up @@ -316,7 +309,7 @@ private async Task DeleteEntityAsync(object obj)
continue;
}

if (_identityMap.TryGetEntityById(d.Id, out object entity))
if (_identityMap.TryGetEntityById(d.Id, out var entity))
{
result.Add((T)entity);
}
Expand Down Expand Up @@ -721,41 +714,46 @@ private IEnumerable<IndexDescriptor> GetDescriptors(Type t)

private async Task MapNew(Document document, object obj)
{
foreach (var descriptor in GetDescriptors(obj.GetType()))
var descriptors = GetDescriptors(obj.GetType());

foreach (var descriptor in descriptors)
{
var mapped = await descriptor.Map(obj);

foreach (var index in mapped)
if (mapped != null)
{
if (index == null)
foreach (var index in mapped)
{
continue;
}
if (index == null)
{
continue;
}

index.AddDocument(document);
index.AddDocument(document);

// if the mapped elements are not meant to be reduced,
// then save them in db, as index
if (descriptor.Reduce == null)
{
if (index.Id == 0)
// if the mapped elements are not meant to be reduced,
// then save them in db, as index
if (descriptor.Reduce == null)
{
_commands.Add(new CreateIndexCommand(index, Enumerable.Empty<int>(), _tablePrefix));
if (index.Id == 0)
{
_commands.Add(new CreateIndexCommand(index, Enumerable.Empty<int>(), _tablePrefix));
}
else
{
_commands.Add(new UpdateIndexCommand(index, Enumerable.Empty<int>(), Enumerable.Empty<int>(), _tablePrefix));
}
}
else
{
_commands.Add(new UpdateIndexCommand(index, Enumerable.Empty<int>(), Enumerable.Empty<int>(), _tablePrefix));
}
}
else
{
// save for later reducing
if (!_maps.TryGetValue(descriptor, out IList<MapState> listmap))
{
_maps.Add(descriptor, listmap = new List<MapState>());
}
// save for later reducing
if (!_maps.TryGetValue(descriptor, out var listmap))
{
_maps.Add(descriptor, listmap = new List<MapState>());
}

listmap.Add(new MapState(index, MapStates.New));
listmap.Add(new MapState(index, MapStates.New));
}
}
}
}
Expand All @@ -766,7 +764,9 @@ private async Task MapNew(Document document, object obj)
/// </summary>
private async Task MapDeleted(Document document, object obj)
{
foreach (var descriptor in _store.Describe(obj.GetType()))
var descriptors = GetDescriptors(obj.GetType());

foreach (var descriptor in descriptors)
{
// If the mapped elements are not meant to be reduced, delete
if (descriptor.Reduce == null || descriptor.Delete == null)
Expand All @@ -777,16 +777,19 @@ private async Task MapDeleted(Document document, object obj)
{
var mapped = await descriptor.Map(obj);

foreach (var index in mapped)
if (mapped != null)
{
// save for later reducing
if (!_maps.TryGetValue(descriptor, out IList<MapState> listmap))
foreach (var index in mapped)
{
_maps.Add(descriptor, listmap = new List<MapState>());
// save for later reducing
if (!_maps.TryGetValue(descriptor, out var listmap))
{
_maps.Add(descriptor, listmap = new List<MapState>());
}

listmap.Add(new MapState(index, MapStates.Delete));
index.RemoveDocument(document);
}

listmap.Add(new MapState(index, MapStates.Delete));
index.RemoveDocument(document);
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions test/YesSql.Tests/CoreTests.cs
Expand Up @@ -940,6 +940,55 @@ public async Task ShouldCreateSeveralMapIndexPerDocument()
}
}

[Fact]
public async Task ShouldDeletePreviousIndexes()
{
// When an index returns multiple map indexes, changing these results should remove the previous ones.

_store.RegisterIndexes<PersonIdentitiesIndexProvider>();

using (var session = _store.CreateSession())
{
var guthrie = new Person
{
Firstname = "Scott",
Lastname = "Guthrie"
};

session.Save(guthrie);
}

using (var session = _store.CreateSession())
{
Assert.Equal(2, await session.QueryIndex<PersonIdentity>().CountAsync());
}

using (var session = _store.CreateSession())
{
var guthrie = await session.Query<Person, PersonIdentity>(x => x.Identity == "Scott").FirstOrDefaultAsync();
guthrie.Lastname = "Gu";

session.Save(guthrie);
}

using (var session = _store.CreateSession())
{
Assert.Equal(2, await session.QueryIndex<PersonIdentity>().CountAsync());
Assert.Equal(1, await session.QueryIndex<PersonIdentity>().Where(x => x.Identity == "Scott").CountAsync());
Assert.Equal(1, await session.QueryIndex<PersonIdentity>().Where(x => x.Identity == "Gu").CountAsync());
}

using (var session = _store.CreateSession())
{
var guthrie = await session.Query<Person, PersonIdentity>(x => x.Identity == "Scott").FirstOrDefaultAsync();
guthrie.Anonymous = true;

session.Save(guthrie);

Assert.Equal(0, await session.QueryIndex<PersonIdentity>().CountAsync());
}
}

[Fact]
public async Task ShouldCreateIndexAndLinkToDocument()
{
Expand Down
4 changes: 2 additions & 2 deletions test/YesSql.Tests/Indexes/PersonIdentity.cs
@@ -1,4 +1,4 @@
using System;
using System;
using YesSql.Indexes;
using YesSql.Tests.Models;

Expand All @@ -20,7 +20,7 @@ public override void Describe(DescribeContext<Person> context)
{
context
.For<PersonIdentity>()
.Map(p => new [] {
.Map(p => p.Anonymous ? null: new [] {
new PersonIdentity(p.Firstname),
new PersonIdentity(p.Lastname)
});
Expand Down
1 change: 1 addition & 0 deletions test/YesSql.Tests/Models/Person.cs
Expand Up @@ -6,5 +6,6 @@ public class Person
public string Firstname { get; set; }
public string Lastname { get; set; }
public int Age { get; set; }
public bool Anonymous { get; set; }
}
}

0 comments on commit db4ec61

Please sign in to comment.