public void CreateQueryRequest_WithAggregate_ReturnsQueryWrappedInQueryRequest() { // Arrange var bucket = new Mock <IBucket>(); bucket.Setup(m => m.Name).Returns("default"); bucket.Setup(m => m.Configuration).Returns(new BucketConfiguration() { PoolConfiguration = new PoolConfiguration(new ClientConfiguration()) }); bucket.Setup(m => m.Cluster).Returns(new Mock <ICluster>().Object); var context = new BucketContext(bucket.Object); var query = context.Query <Beer>().Where(p => p.Name == "name"); // Act var result = LinqQueryRequest.CreateQueryRequest(query, p => p.Average(q => q.Abv)); // Assert const string queryStr = "SELECT AVG(`Extent1`.`abv`) as `result` FROM `default` as `Extent1` WHERE (`Extent1`.`name` = 'name')"; Assert.NotNull(result); Assert.AreEqual(queryStr, result.GetOriginalStatement()); Assert.True(result.ScalarResultBehavior.ResultExtractionRequired); }
/// <summary> /// Execute a Couchbase query asynchronously. /// </summary> /// <typeparam name="T">Type being queried.</typeparam> /// <typeparam name="TResult">Type returned by <paramref name="additionalExpression"/>.</typeparam> /// <param name="source">Query to execute asynchronously. Must be a Couchbase LINQ query.</param> /// <param name="additionalExpression">Additional expressions to apply to the query before executing. Typically used for aggregates.</param> /// <returns>Task which contains the query result when completed.</returns> /// <remarks> /// <para>The expression contained in <paramref name="additionalExpression"/> is applied to the query before /// it is executed asynchrounously. Typically, this would be used to apply an aggregate, First, Single, /// or other operation to the query that normall triggers immediate query execution. Passing these actions /// in <paramref name="additionalExpression"/> delays their execution so that they can be handled asynchronously.</para> /// <para><paramref name="additionalExpression"/> must return a scalar value or a single object. It should not return another /// instance of <see cref="IQueryable{T}"/>.</para> /// </remarks> /// <example> /// var document = await query.ExecuteAsync(query => query.First()); /// </example> /// <example> /// var avg = await query.ExecuteAsync(query => query.Average(p => p.Abv)); /// </example> public static async Task <TResult> ExecuteAsync <T, TResult>(this IQueryable <T> source, Expression <Func <IQueryable <T>, TResult> > additionalExpression) { if (source is EnumerableQuery) { // Allow ExecuteAsync to simply run synchronously when executed against an in-memory collection // This supports injecting mock IBucketContext instances into unit tests of business logic // https://github.com/couchbaselabs/Linq2Couchbase/issues/191 var additionalFunction = additionalExpression.Compile(); return(additionalFunction(source)); } EnsureBucketQueryable(source, "ExecuteAsync", "source"); if (typeof(TResult).GetTypeInfo().IsGenericTypeDefinition&& (typeof(TResult).GetGenericTypeDefinition() == typeof(IQueryable <>))) { throw new ArgumentException("additionalExpression must return a scalar value, not IQueryable.", "additionalExpression"); } var queryRequest = LinqQueryRequest.CreateQueryRequest(source, additionalExpression); return(await ((IBucketQueryExecutorProvider)source).BucketQueryExecutor.ExecuteSingleAsync <TResult>(queryRequest) .ConfigureAwait(false)); }
public void CreateQueryRequest_First_ReturnsQueryWrappedInQueryRequest() { // Arrange var bucket = new Mock <IBucket>(); bucket.Setup(m => m.Name).Returns("default"); bucket.Setup(m => m.Configuration).Returns(new BucketConfiguration() { PoolConfiguration = new PoolConfiguration(new ClientConfiguration()) }); bucket.Setup(m => m.Cluster).Returns(new Mock <ICluster>().Object); var context = new BucketContext(bucket.Object); var query = context.Query <Brewery>().Where(p => p.Name == "name"); // Act var result = LinqQueryRequest.CreateQueryRequest(query, p => p.First()); // Assert const string queryStr = "SELECT `Extent1`.* FROM `default` as `Extent1` WHERE (`Extent1`.`name` = 'name') LIMIT 1"; Assert.NotNull(result); Assert.AreEqual(queryStr, result.GetOriginalStatement()); Assert.False(result.ReturnDefaultWhenEmpty); }
public void CreateQueryRequest_ScanWait_HasSetting() { // Arrange var bucket = new Mock <IBucket>(); bucket.Setup(m => m.Name).Returns("default"); bucket.Setup(m => m.Configuration).Returns(new BucketConfiguration() { PoolConfiguration = new PoolConfiguration(new ClientConfiguration()) }); bucket.Setup(m => m.Cluster).Returns(new Mock <ICluster>().Object); var scanWait = TimeSpan.FromMinutes(1); var context = new BucketContext(bucket.Object); var query = context.Query <Brewery>().ScanWait(scanWait).Where(p => p.Name == "name"); // Act var result = LinqQueryRequest.CreateQueryRequest(query); // Assert Assert.NotNull(result); Assert.AreEqual(scanWait.TotalMilliseconds + "ms", result.GetFormValues()["scan_wait"]); }
public void CreateQueryRequest_ScanConsistency_HasSetting() { // Arrange var bucket = new Mock <IBucket>(); bucket.Setup(m => m.Name).Returns("default"); bucket.Setup(m => m.Configuration).Returns(new BucketConfiguration() { PoolConfiguration = new PoolConfiguration(new ClientConfiguration()) }); bucket.Setup(m => m.Cluster).Returns(new Mock <ICluster>().Object); var context = new BucketContext(bucket.Object); var query = context.Query <Brewery>().ScanConsistency(ScanConsistency.RequestPlus).Where(p => p.Name == "name"); // Act var result = LinqQueryRequest.CreateQueryRequest(query); // Assert Assert.NotNull(result); Assert.AreEqual("request_plus", result.GetFormValues()["scan_consistency"]); }
public void CreateQueryRequest_All_ReturnsQueryWrappedInQueryRequest() { // Arrange var bucket = new Mock <IBucket>(); bucket.Setup(m => m.Name).Returns("default"); bucket.Setup(m => m.Configuration).Returns(new BucketConfiguration() { PoolConfiguration = new PoolConfiguration(new ClientConfiguration()) }); bucket.Setup(m => m.Cluster).Returns(new Mock <ICluster>().Object); var context = new BucketContext(bucket.Object); var query = context.Query <Brewery>(); // Act var result = LinqQueryRequest.CreateQueryRequest(query, p => p.All(q => q.Name == "name")); // Assert const string queryStr = "SELECT false as result FROM `default` as `Extent1` WHERE NOT ((`Extent1`.`name` = 'name')) LIMIT 1"; Assert.NotNull(result); Assert.AreEqual(queryStr, result.GetOriginalStatement()); Assert.True(result.ScalarResultBehavior.ResultExtractionRequired); Assert.AreEqual(true, result.ScalarResultBehavior.NoRowsResult); }
/// <summary> /// Execute a Couchbase query asynchronously. /// </summary> /// <typeparam name="T">Type being queried.</typeparam> /// <param name="source">Query to execute asynchronously. Must be a Couchbase LINQ query.</param> /// <returns>Task which contains the query result when completed.</returns> /// <example> /// var results = await query.ExecuteAsync(); /// </example> public static async Task <IEnumerable <T> > ExecuteAsync <T>(this IQueryable <T> source) { EnsureBucketQueryable(source, "ExecuteAsync", "source"); var queryRequest = LinqQueryRequest.CreateQueryRequest(source); return(await ((IBucketQueryExecutorProvider)source).BucketQueryExecutor.ExecuteCollectionAsync <T>(queryRequest) .ConfigureAwait(false)); }
/// <summary> /// Execute a Couchbase query asynchronously. /// </summary> /// <typeparam name="T">Type being queried.</typeparam> /// <typeparam name="TResult">Type returned by <paramref name="additionalExpression"/>.</typeparam> /// <param name="source">Query to execute asynchronously. Must be a Couchbase LINQ query.</param> /// <param name="additionalExpression">Additional expressions to apply to the query before executing. Typically used for aggregates.</param> /// <returns>Task which contains the query result when completed.</returns> /// <remarks> /// <para>The expression contained in <paramref name="additionalExpression"/> is applied to the query before /// it is executed asynchrounously. Typically, this would be used to apply an aggregate, First, Single, /// or other operation to the query that normall triggers immediate query execution. Passing these actions /// in <paramref name="additionalExpression"/> delays their execution so that they can be handled asynchronously.</para> /// <para><paramref name="additionalExpression"/> must return a scalar value or a single object. It should not return another /// instance of <see cref="IQueryable{T}"/>.</para> /// </remarks> /// <example> /// var document = await query.ExecuteAsync(query => query.First()); /// </example> /// <example> /// var avg = await query.ExecuteAsync(query => query.Average(p => p.Abv)); /// </example> public static async Task <TResult> ExecuteAsync <T, TResult>(this IQueryable <T> source, Expression <Func <IQueryable <T>, TResult> > additionalExpression) { EnsureBucketQueryable(source, "ExecuteAsync", "source"); if (typeof(TResult).GetTypeInfo().IsGenericTypeDefinition&& (typeof(TResult).GetGenericTypeDefinition() == typeof(IQueryable <>))) { throw new ArgumentException("additionalExpression must return a scalar value, not IQueryable.", "additionalExpression"); } var queryRequest = LinqQueryRequest.CreateQueryRequest(source, additionalExpression); return(await ((IBucketQueryExecutorProvider)source).BucketQueryExecutor.ExecuteSingleAsync <TResult>(queryRequest) .ConfigureAwait(false)); }
/// <summary> /// Execute a Couchbase query asynchronously. /// </summary> /// <typeparam name="T">Type being queried.</typeparam> /// <param name="source">Query to execute asynchronously. Must be a Couchbase LINQ query.</param> /// <returns>Task which contains the query result when completed.</returns> /// <example> /// var results = await query.ExecuteAsync(); /// </example> public static async Task <IEnumerable <T> > ExecuteAsync <T>(this IQueryable <T> source) { if (source is EnumerableQuery) { // Allow ExecuteAsync to simply run synchronously when executed against an in-memory collection // This supports injecting mock IBucketContext instances into unit tests of business logic // https://github.com/couchbaselabs/Linq2Couchbase/issues/191 return(source.AsEnumerable()); } EnsureBucketQueryable(source, "ExecuteAsync", "source"); var queryRequest = LinqQueryRequest.CreateQueryRequest(source); return(await ((IBucketQueryExecutorProvider)source).BucketQueryExecutor.ExecuteCollectionAsync <T>(queryRequest) .ConfigureAwait(false)); }