/// <summary> /// Emulates Nest for N1QL against an IEnumerable /// </summary> /// <typeparam name="TOuter">Type of the source sequence</typeparam> /// <typeparam name="TInner">Type of the inner sequence being nested</typeparam> /// <typeparam name="TResult">Type of the result sequence</typeparam> /// <param name="outer"></param> /// <param name="inner">Sequence to be nested</param> /// <param name="keySelector">Expression to get the list of keys to nest for an item in the source sequence. Should return a list of strings.</param> /// <param name="resultSelector">Expression that returns the result</param> /// <param name="innerNest">Excludes results where no matches are found in the inner sequence</param> /// <returns></returns> private static IEnumerable <TResult> Nest <TOuter, TInner, TResult>( this IEnumerable <TOuter> outer, IEnumerable <TInner> inner, Func <TOuter, IEnumerable <string> > keySelector, Func <TOuter, IEnumerable <TInner>, TResult> resultSelector, bool innerNest) where TInner : IDocumentMetadataProvider { if (inner == null) { throw new ArgumentNullException("inner"); } if (outer == null) { throw new ArgumentNullException("outer"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (resultSelector == null) { throw new ArgumentNullException("resultSelector"); } // Create a dictionary on the inner sequence, based on document key // This ensures that the inner sequence is only enumerated once // And that lookups are fast var innerDictionary = inner.ToDictionary(p => N1Ql.Key(p)); return(outer .Select(outerDocument => { var keys = keySelector.Invoke(outerDocument); List <TInner> innerDocuments = null; if (keys != null) { innerDocuments = keys.Select(key => { TInner innerDocument; if (!innerDictionary.TryGetValue(key, out innerDocument)) { innerDocument = default(TInner); // return null when not found } return innerDocument; }) .Where(p => p != null) // skip any documents that weren't found in the dictionary .ToList(); } if (innerNest && (innerDocuments == null || innerDocuments.Count == 0)) { // For inner nest, return null if there are no inner documents return default(TResult); } return resultSelector.Invoke(outerDocument, innerDocuments); }) .Where(p => p != null)); // Filter out any null results returned due to inner nest or a null from the resultSelector }
public void Test_LeftJoin_SortAndFilter() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = from beer in QueryFactory.Queryable <Beer>(mockBucket.Object) join breweryGroup in QueryFactory.Queryable <Brewery>(mockBucket.Object) on beer.BreweryId equals N1Ql.Key(breweryGroup) into bg from brewery in bg.DefaultIfEmpty() where beer.Abv > 4 orderby brewery.Name, beer.Name select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; const string expected = "SELECT `Extent1`.`name` as `Name`, `Extent1`.`abv` as `Abv`, `Extent2`.`name` as `BreweryName` " + "FROM `default` as `Extent1` " + "LEFT JOIN `default` as `Extent2` " + "ON KEYS `Extent1`.`brewery_id` " + "WHERE (`Extent1`.`abv` > 4) " + "ORDER BY `Extent2`.`name` ASC, `Extent1`.`name` ASC"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void BeerSample_Tests() { var db = new BeerSample(); var query = from beer in db.Beers join brewery in db.Breweries on beer.BreweryId equals N1Ql.Key(brewery) select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; foreach (var beer in query) { Console.WriteLine(beer.Name); } }
/// <summary> /// Emulates UseKeys for N1QL against an IEnumerable /// </summary> /// <typeparam name="T">Type of the source sequence</typeparam> /// <param name="items">Items being filtered</param> /// <param name="keys">Keys to be selected</param> /// <returns></returns> public static IEnumerable <T> UseKeys <T>( this IEnumerable <T> items, IEnumerable <string> keys) where T : IDocumentMetadataProvider { if (items == null) { throw new ArgumentNullException("items"); } if (keys == null) { throw new ArgumentNullException("keys"); } return(items.Where(p => keys.Contains(N1Ql.Key(p)))); }
public void Test_IsNotMissing_ByName() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = QueryFactory.Queryable <Contact>(mockBucket.Object) .Where(p => N1Ql.IsNotMissing(p, "test")); const string expected = "SELECT `Extent1`.* FROM `default` as `Extent1` WHERE `Extent1`.`test` IS NOT MISSING"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_IsMissing_SubstiteWithDefault() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = QueryFactory.Queryable <Contact>(mockBucket.Object) .Select(p => new { age = N1Ql.IsMissing(p.Age) ? 10 : p.Age }); const string expected = "SELECT CASE WHEN `Extent1`.`age` IS MISSING THEN 10 ELSE `Extent1`.`age` END as `age` FROM `default` as `Extent1`"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_Meta_Keyword() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = QueryFactory.Queryable <Contact>(mockBucket.Object) .Select(p => N1Ql.Meta(p)); const string expected = "SELECT META(`Extent1`) FROM `default` as `Extent1`"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_IsNotValued_ByProperty() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = QueryFactory.Queryable <Contact>(mockBucket.Object) .Where(p => N1Ql.IsNotValued(p.Age)); const string expected = "SELECT `Extent1`.* FROM `default` as `Extent1` WHERE `Extent1`.`age` IS NOT VALUED"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_Meta_Keyword_With_Projection() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = QueryFactory.Queryable <Contact>(mockBucket.Object) .Select(c => new { c.Age, Meta = N1Ql.Meta(c) }); const string expected = "SELECT `Extent1`.`age` as `Age`, META(`Extent1`) as `Meta` FROM `default` as `Extent1`"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Map2PocoTests_Simple_Projections_MetaId() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var beers = (from b in bucket.Queryable <Beer>() where b.Type == "beer" select new { name = b.Name, id = N1Ql.Meta(b).Id }). Take(10); foreach (var b in beers) { Console.WriteLine("{0} has id {1}", b.name, b.id); } } } }
public void JoinTests_InnerJoin_Simple() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var beers = from beer in bucket.Queryable <Beer>() join brewery in bucket.Queryable <Brewery>() on beer.BreweryId equals N1Ql.Key(brewery) select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; foreach (var b in beers.Take(10)) { Console.WriteLine("Beer {0} with ABV {1} is from {2}", b.Name, b.Abv, b.BreweryName); } } } }
public void Map2PocoTests_Simple_Projections_MetaWhere() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var beers = (from b in bucket.Queryable <Beer>() where b.Type == "beer" && N1Ql.Meta(b).Type == "json" select new { name = b.Name }). Take(10); foreach (var b in beers) { Console.WriteLine("{0} is a JSON document", b.name); } } } }
public void Test_InnerJoin_Simple() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = from beer in QueryFactory.Queryable <Beer>(mockBucket.Object) join brewery in QueryFactory.Queryable <Brewery>(mockBucket.Object) on beer.BreweryId equals N1Ql.Key(brewery) select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; const string expected = "SELECT `Extent1`.`name` as `Name`, `Extent1`.`abv` as `Abv`, `Extent2`.`name` as `BreweryName` " + "FROM `default` as `Extent1` " + "INNER JOIN `default` as `Extent2` " + "ON KEYS `Extent1`.`brewery_id`"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void JoinTests_InnerJoin_Prefiltered() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var beers = from beer in bucket.Queryable <Beer>().Where(p => p.Type == "beer") join brewery in bucket.Queryable <Brewery>().Where(p => p.Type == "brewery") on beer.BreweryId equals N1Ql.Key(brewery) where brewery.Geo.Longitude > -80 orderby beer.Name select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; foreach (var b in beers.Take(10)) { Console.WriteLine("Beer {0} with ABV {1} is from {2}", b.Name, b.Abv, b.BreweryName); } } } }
public void JoinTests_LeftJoin_SortAndFilter() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var beers = from beer in bucket.Queryable <Beer>() join breweryGroup in bucket.Queryable <Brewery>() on beer.BreweryId equals N1Ql.Key(breweryGroup) into bg from brewery in bg.DefaultIfEmpty() where beer.Abv > 4 orderby brewery.Name, beer.Name select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; foreach (var b in beers.Take(10)) { Console.WriteLine("Beer {0} with ABV {1} is from {2}", b.Name, b.Abv, b.BreweryName); } } } }
public void Test_LeftJoin_Prefiltered() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = from beer in QueryFactory.Queryable <Beer>(mockBucket.Object).Where(p => p.Type == "beer") join breweryGroup in QueryFactory.Queryable <Brewery>(mockBucket.Object).Where(p => p.Type == "brewery") on beer.BreweryId equals N1Ql.Key(breweryGroup) into bg from brewery in bg.DefaultIfEmpty() select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; const string expected = "SELECT `Extent1`.`name` as `Name`, `Extent1`.`abv` as `Abv`, `Extent2`.`name` as `BreweryName` " + "FROM `default` as `Extent1` " + "LEFT JOIN `default` as `Extent2` " + "ON KEYS `Extent1`.`brewery_id` " + "WHERE (`Extent1`.`type` = 'beer') AND (`Extent2`.`type` = 'brewery')"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_Meta_Fakeable() { // Confirms that the N1Ql.Meta operation can be faked for unit testing in a client application var metadata = new DocumentMetadata() { Id = "testid" }; var mockObject = new Mock <Brewery>(); var mockMetadataProvider = mockObject.As <IDocumentMetadataProvider>(); mockMetadataProvider.Setup(p => p.GetMetadata()).Returns(metadata); var data = (new List <Brewery> { mockObject.Object }).AsQueryable(); var query = from p in data select N1Ql.Meta(p).Id; Assert.AreEqual(metadata.Id, query.First()); }
public void Test_GroupByAfterJoin() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = from beer in QueryFactory.Queryable <Beer>(mockBucket.Object) join brewery in QueryFactory.Queryable <Brewery>(mockBucket.Object) on beer.BreweryId equals N1Ql.Key(brewery) group beer by brewery.Name into g select new { breweryName = g.Key, avgAbv = g.Average(p => p.Abv) }; const string expected = "SELECT `Extent2`.`name` as `breweryName`, AVG(`Extent1`.`abv`) as `avgAbv` " + "FROM `default` as `Extent1` " + "INNER JOIN `default` as `Extent2` ON KEYS `Extent1`.`brewery_id` " + "GROUP BY `Extent2`.`name`"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void Test_InnerJoin_SortAndFilter() { var mockBucket = new Mock <IBucket>(); mockBucket.SetupGet(e => e.Name).Returns("default"); var query = from beer in QueryFactory.Queryable <Beer>(mockBucket.Object) join brewery in QueryFactory.Queryable <Brewery>(mockBucket.Object) on beer.BreweryId equals N1Ql.Key(brewery) where brewery.Geo.Longitude > -80 orderby beer.Name select new { beer.Name, beer.Abv, BreweryName = brewery.Name }; const string expected = "SELECT `Extent1`.`name` as `Name`, `Extent1`.`abv` as `Abv`, `Extent2`.`name` as `BreweryName` " + "FROM `default` as `Extent1` " + "INNER JOIN `default` as `Extent2` " + "ON KEYS `Extent1`.`brewery_id` " + "WHERE (`Extent2`.`geo`.`lon` > -80) " + "ORDER BY `Extent1`.`name` ASC"; var n1QlQuery = CreateN1QlQuery(mockBucket.Object, query.Expression); Assert.AreEqual(expected, n1QlQuery); }
public void AggregateTests_SimpleAverage() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var avg = bucket.Queryable <Beer>().Where(p => p.Type == "beer" && N1Ql.IsValued(p.Abv)).Average(p => p.Abv); Console.WriteLine("Average ABV of all beers is {0}", avg); } } }
public void AggregateTests_JoinBeforeGroupByAndMultipartKey() { using (var cluster = new Cluster(TestConfigurations.DefaultConfig())) { using (var bucket = cluster.OpenBucket("beer-sample")) { var breweries = from beer in bucket.Queryable <Beer>() join brewery in bucket.Queryable <Brewery>() on beer.BreweryId equals N1Ql.Key(brewery) where beer.Type == "beer" group beer by new { breweryid = beer.BreweryId, breweryName = brewery.Name } into g select new { g.Key.breweryName, count = g.Count(), avgAbv = g.Average(p => p.Abv) }; foreach (var brewery in breweries) { Console.WriteLine("Brewery {0} has {1} beers with {2:f2} average ABV", brewery.breweryName, brewery.count, brewery.avgAbv); } } } }