Skip to content

Commit

Permalink
Adding support for recursion in indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
ayende committed Sep 20, 2011
1 parent 3c60af6 commit 6c25bbf
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Raven.Client.Lightweight/Indexes/AbstractIndexCreationTask.cs
Expand Up @@ -49,6 +49,14 @@ public abstract class AbstractIndexCreationTask
public DocumentConvention Conventions { get; set; }

#if !NET_3_5
/// <summary>
/// Allows to use lambdas recursively
/// </summary>
protected IEnumerable<TResult> Recurse<TSource,TResult>(TSource source, Func<TSource, TResult> func)
{
throw new NotSupportedException("This can only be run on the server side");
}

/// <summary>
/// Allows to use lambdas over dynamic
/// </summary>
Expand Down
21 changes: 21 additions & 0 deletions Raven.Database/Linq/AbstractViewGenerator.cs
Expand Up @@ -113,6 +113,27 @@ protected IEnumerable<dynamic> Hierarchy(object source, string name)
}
}

protected IEnumerable<dynamic> Recurse(object item, Func<dynamic ,dynamic> func)
{
if (item == null)
return Enumerable.Empty<dynamic>();

var resultsOrdered = new List<dynamic>();

var results = new HashSet<object>();
item = func(item);
while (item != null)
{
if (results.Add(item) == false)
break;

resultsOrdered.Add(item);
item = func(item);
}

return new DynamicJsonObject.DynamicList(resultsOrdered.ToArray());
}

public void AddQueryParameterForMap(string field)
{
mapFields.Add(field);
Expand Down
93 changes: 93 additions & 0 deletions Raven.Tests/Bugs/RecursiveQueries.cs
@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Linq;
using Raven.Client.Indexes;
using Xunit;
using Raven.Client.Linq;

namespace Raven.Tests.Bugs
{
public class RecursiveQueries : RavenTest
{
[Fact]
public void ShouldBePossible()
{
using(var store = NewDocumentStore())
{
new CategoryWithParentsAndChildren().Execute(store);

using(var session = store.OpenSession())
{
var root = new Category
{
Name = "Root"
};
session.Store(root);
var category = new Category
{
Name = "Child",
ParentId = root.Id
};
session.Store(category);
session.Store(new Category
{
Name = "Grandchild",
ParentId = category.Id
});
session.SaveChanges();
}

using(var session = store.OpenSession())
{
List<CategoryHeaderWithParents> categoryHeaderWithParentses = session.Query<CategoryHeaderWithParents, CategoryWithParentsAndChildren>()
.Customize(x=>x.WaitForNonStaleResults())
.Where(x=>x.Name == "Grandchild")
.ToList();

Assert.Equal("Grandchild", categoryHeaderWithParentses[0].Name);
Assert.Equal("Child", categoryHeaderWithParentses[0].Parents[0].Name);
Assert.Equal("Root", categoryHeaderWithParentses[0].Parents[1].Name);
}
}
}

public class CategoryWithParentsAndChildren : AbstractIndexCreationTask<Category>
{
public CategoryWithParentsAndChildren()
{
Map = categories => from category in categories
select new {category.Id, category.Name, category.ParentId};
TransformResults = (database, categories) =>
from category in categories
let parentCategories = Recurse(category, c => database.Load<Category>(c.ParentId))
select new
{
category.Id,
category.Name,
Parents =
(
from parent in parentCategories
select new {parent.Id, parent.Name}
)
};
}
}

public class CategoryHeader
{
public string Id { get; set; }
public string Name { get; set; }
}

public class CategoryHeaderWithParents : CategoryHeader
{
public CategoryHeader[] Parents { get; set; }
}

public class Category
{
public string Id { get; set; }
public string Name { get; set; }
public string ParentId { get; set; }
}
}
}
1 change: 1 addition & 0 deletions Raven.Tests/Raven.Tests.csproj
Expand Up @@ -205,6 +205,7 @@
<Compile Include="Bugs\QueryingOnEmptyString.cs" />
<Compile Include="Bugs\QueryOptimizerOnStaticIndex.cs" />
<Compile Include="Bugs\RacielrodTest.cs" />
<Compile Include="Bugs\RecursiveQueries.cs" />
<Compile Include="Bugs\RoundCrisis.cs" />
<Compile Include="Bugs\SelfReference.cs" />
<Compile Include="Bugs\SerializingAndDeserializingWithRaven.cs" />
Expand Down

0 comments on commit 6c25bbf

Please sign in to comment.