Skip to content

Instantly share code, notes, and snippets.

@pauldambra
Last active December 14, 2015 07:38
Show Gist options
  • Save pauldambra/5051550 to your computer and use it in GitHub Desktop.
Save pauldambra/5051550 to your computer and use it in GitHub Desktop.
Trying to understand why I suck at making RavenDB indexes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Indexes;
using Raven.Client.Listeners;
using Xunit;
namespace BmcMailTests
{
/// <summary>
/// Requires Xunit, RavenDB.Embedded and RavenDB.Client.
/// Which were installed using Nuget. Version 2.0.2261 of Raven and
/// 1.9.1 Xunit
/// Demonstrates an attempt to write a RavenDB index that fails magnificently
/// </summary>
public class RavenIndexTest
{
[Fact]
public void DemonstrateAssertionsPassWhenIndexIsNotUsed()
{
var documentStore = SetupDocumentStore();
using (documentStore)
{
SetupData(documentStore);
TestDataWithoutUsingIndex(documentStore);
}
}
[Fact]
public void DemonstrateAssertionsFailWhenIndexIsUsed()
{
var documentStore = SetupDocumentStore();
using (documentStore)
{
SetupData(documentStore);
using (var session = documentStore.OpenSession())
{
var results = session.Query<MailingWithRecipientCount.Result,
MailingWithRecipientCount>();
Assert.NotNull(results);
//calling ToList() throws Input string was not in a correct format.
List<MailingWithRecipientCount.Result> resultsList = null;
try
{
resultsList = results.ToList();
}
catch (FormatException e)
{
Assert.True(false,e.Message);
}
Assert.NotNull(resultsList);
Assert.Equal(1, resultsList.Count());
Assert.Equal(10, resultsList.First().RecipientCount);
}
}
}
private static void TestDataWithoutUsingIndex(IDocumentStore documentStore)
{
using (var proofSession = documentStore.OpenSession())
{
//prove the mailing is there
var allMailings = proofSession.Query<Mailing>();
Assert.NotNull(allMailings);
Assert.Equal(1, allMailings.Count());
Assert.Equal(1, allMailings.First().Id);
//prove the recipients are there
var allRecipients = proofSession.Query<Recipient>();
Assert.NotNull(allRecipients);
Assert.Equal(10, allRecipients.Count());
Assert.Equal(4, allRecipients.Count(ar => ar.Status == RecipientStatus.Pending));
Assert.Equal(6, allRecipients.Count(ar => ar.Status == RecipientStatus.Mailed));
}
}
private static void SetupData(IDocumentStore documentStore)
{
using (var setupSession = documentStore.OpenSession())
{
setupSession.Store(new Mailing
{
Sender = "a sender",
Subject = "a subject"
});
for (var i = 0; i < 4; i++)
{
setupSession.Store(new Recipient {MailingId = 1});
}
for (var i = 0; i < 6; i++)
{
setupSession.Store(new Recipient
{
MailingId = 1,
Status = RecipientStatus.Mailed
});
}
setupSession.SaveChanges();
}
}
private static EmbeddableDocumentStore SetupDocumentStore()
{
var documentStore = new EmbeddableDocumentStore {RunInMemory = true};
//setup the store
documentStore.RegisterListener(new NoStaleQueriesAllowed());
documentStore.Initialize();
IndexCreation.CreateIndexes(Assembly.GetExecutingAssembly(), documentStore);
return documentStore;
}
public class NoStaleQueriesAllowed : IDocumentQueryListener
{
public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization)
{
queryCustomization.WaitForNonStaleResults();
}
}
public class Mailing
{
public Mailing()
{
Created = DateTime.Now;
}
public int Id { get; set; }
public string Sender { get; set; }
public string Subject { get; set; }
public DateTime Created { get; set; }
}
public enum RecipientStatus
{
Pending,
Sending,
Mailed,
Cancelled,
Bad
}
public class Recipient
{
public Recipient()
{
Status = RecipientStatus.Pending;
}
public RecipientStatus Status { get; set; }
public int MailingId { get; set; }
}
public class MailingWithRecipientCount : AbstractMultiMapIndexCreationTask<MailingWithRecipientCount.Result>
{
public class Result
{
public int MailingId { get; set; }
public string MailingSubject { get; set; }
public string MailingSender { get; set; }
public int RecipientCount { get; set; }
}
public MailingWithRecipientCount()
{
AddMap<Mailing>(mailings => from mailing in mailings
select new
{
MailingId = mailing.Id,
MailingSender = mailing.Sender,
MailingSubject = mailing.Subject,
RecipientCount = 0
});
AddMap<Recipient>(recipients => from recipient in recipients
select new
{
recipient.MailingId,
MailingSender = (string)null,
MailingSubject = (string)null,
RecipientCount = 1
});
Reduce = results => from result in results
group result by result.MailingId
into g
select new
{
MailingId = g.Key,
g.First(result => result != null).MailingSender,
g.First(result => result != null).MailingSubject,
RecipientCount = g.Sum(r => r.RecipientCount)
};
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment