internal static SubscriptionCreationOptions CreateSubscriptionOptionsFromGeneric <T>( DocumentConventions conventions, SubscriptionCreationOptions criteria, Expression <Func <T, bool> > predicate, Expression <Func <T, object> > project, Action <ISubscriptionIncludeBuilder <T> > includes) { criteria ??= new SubscriptionCreationOptions(); var collectionName = conventions.GetCollectionName(typeof(T)); StringBuilder queryBuilder; if (criteria.Query != null) { queryBuilder = new StringBuilder(criteria.Query); } else { queryBuilder = new StringBuilder(); var tType = typeof(T); var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>); if (includeRevisions) { collectionName = conventions.GetCollectionName(tType.GenericTypeArguments[0]); } queryBuilder.Append("from '"); StringExtensions.EscapeString(queryBuilder, collectionName); queryBuilder.Append('\''); if (includeRevisions) { queryBuilder.Append(" (Revisions = true)"); } criteria.Query = queryBuilder.Append(" as doc").ToString(); } if (predicate != null) { var script = predicate.CompileToJavascript( new JavascriptCompilationOptions( JsCompilationFlags.BodyOnly, JavascriptConversionExtensions.MathSupport.Instance, new JavascriptConversionExtensions.DictionarySupport(), JavascriptConversionExtensions.LinqMethodsSupport.Instance, new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(conventions), new JavascriptConversionExtensions.ConstSupport(conventions), new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"), JavascriptConversionExtensions.ToStringSupport.Instance, JavascriptConversionExtensions.DateTimeSupport.Instance, JavascriptConversionExtensions.TimeSpanSupport.Instance, JavascriptConversionExtensions.InvokeSupport.Instance, JavascriptConversionExtensions.NullCoalescingSupport.Instance, JavascriptConversionExtensions.NestedConditionalSupport.Instance, JavascriptConversionExtensions.StringSupport.Instance, new JavascriptConversionExtensions.IdentityPropertySupport(conventions) )); queryBuilder .Insert(0, $"declare function predicate() {{ return {script} }}{Environment.NewLine}") .AppendLine() .Append("where predicate.call(doc)"); } if (project != null) { var script = project.CompileToJavascript( new JavascriptCompilationOptions( JsCompilationFlags.BodyOnly, JavascriptConversionExtensions.MathSupport.Instance, new JavascriptConversionExtensions.DictionarySupport(), JavascriptConversionExtensions.LinqMethodsSupport.Instance, new JavascriptConversionExtensions.ConstSupport(conventions), JavascriptConversionExtensions.ToStringSupport.Instance, JavascriptConversionExtensions.DateTimeSupport.Instance, JavascriptConversionExtensions.TimeSpanSupport.Instance, JavascriptConversionExtensions.InvokeSupport.Instance, JavascriptConversionExtensions.NullCoalescingSupport.Instance, JavascriptConversionExtensions.StringSupport.Instance, JavascriptConversionExtensions.NestedConditionalSupport.Instance, new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"), new JavascriptConversionExtensions.IdentityPropertySupport(conventions), JavascriptConversionExtensions.CounterSupport.Instance, JavascriptConversionExtensions.CompareExchangeSupport.Instance, new JavascriptConversionExtensions.LoadSupport(), JavascriptConversionExtensions.MemberInit.Instance )); queryBuilder .AppendLine() .Append("select ") .Append(script); } if (includes != null) { var builder = new IncludeBuilder <T>(conventions); includes(builder); var numberOfIncludesAdded = 0; if (builder.DocumentsToInclude?.Count > 0) { queryBuilder .AppendLine() .Append("include "); foreach (var inc in builder.DocumentsToInclude) { var include = "doc." + inc; if (numberOfIncludesAdded > 0) { queryBuilder.Append(","); } if (IncludesUtil.RequiresQuotes(include, out var escapedInclude)) { queryBuilder .Append("'") .Append(escapedInclude) .Append("'"); } else { queryBuilder.Append(QueryToken.IsKeyword(include) ? $"'{include}'" : include); } numberOfIncludesAdded++; } } if (builder.AllCounters) { if (numberOfIncludesAdded == 0) { queryBuilder .AppendLine() .Append("include "); } var token = CounterIncludesToken.All(string.Empty); token.WriteTo(queryBuilder); numberOfIncludesAdded++; } else if (builder.CountersToInclude?.Count > 0) { if (numberOfIncludesAdded == 0) { queryBuilder .AppendLine() .Append("include "); } foreach (var counterName in builder.CountersToInclude) { if (numberOfIncludesAdded > 0) { queryBuilder.Append(","); } var token = CounterIncludesToken.Create(string.Empty, counterName); token.WriteTo(queryBuilder); numberOfIncludesAdded++; } } if (builder.TimeSeriesToInclude != null) { foreach (var timeSeriesRange in builder.TimeSeriesToInclude) { if (numberOfIncludesAdded == 0) { queryBuilder .AppendLine() .Append("include "); } if (numberOfIncludesAdded > 0) { queryBuilder.Append(","); } var token = TimeSeriesIncludesToken.Create(string.Empty, timeSeriesRange); token.WriteTo(queryBuilder); numberOfIncludesAdded++; } } } criteria.Query = queryBuilder.ToString(); return(criteria); }
internal static SubscriptionCreationOptions CreateSubscriptionOptionsFromGeneric <T>( DocumentConventions conventions, SubscriptionCreationOptions criteria, Expression <Func <T, bool> > predicate, Expression <Func <T, object> > project, Action <ISubscriptionIncludeBuilder <T> > includes) { criteria ??= new SubscriptionCreationOptions(); var collectionName = conventions.GetCollectionName(typeof(T)); if (criteria.Query == null) { var tType = typeof(T); var includeRevisions = tType.IsConstructedGenericType && tType.GetGenericTypeDefinition() == typeof(Revision <>); if (includeRevisions) { collectionName = conventions.GetCollectionName(tType.GenericTypeArguments[0]); } var builder = new StringBuilder("from '"); StringExtensions.EscapeString(builder, collectionName); builder.Append('\''); if (includeRevisions) { builder.Append(" (Revisions = true)"); } criteria.Query = builder.Append(" as doc").ToString(); } if (predicate != null) { var script = predicate.CompileToJavascript( new JavascriptCompilationOptions( JsCompilationFlags.BodyOnly, JavascriptConversionExtensions.MathSupport.Instance, new JavascriptConversionExtensions.DictionarySupport(), JavascriptConversionExtensions.LinqMethodsSupport.Instance, new JavascriptConversionExtensions.SubscriptionsWrappedConstantSupport(conventions), new JavascriptConversionExtensions.ConstSupport(conventions), new JavascriptConversionExtensions.ReplaceParameterWithNewName(predicate.Parameters[0], "this"), JavascriptConversionExtensions.ToStringSupport.Instance, JavascriptConversionExtensions.DateTimeSupport.Instance, JavascriptConversionExtensions.TimeSpanSupport.Instance, JavascriptConversionExtensions.InvokeSupport.Instance, JavascriptConversionExtensions.NullCoalescingSupport.Instance, JavascriptConversionExtensions.NestedConditionalSupport.Instance, JavascriptConversionExtensions.StringSupport.Instance )); criteria.Query = $"declare function predicate() {{ return {script} }}{Environment.NewLine}" + $"{criteria.Query}{Environment.NewLine}" + "where predicate.call(doc)"; } if (project != null) { var script = project.CompileToJavascript( new JavascriptCompilationOptions( JsCompilationFlags.BodyOnly, JavascriptConversionExtensions.MathSupport.Instance, new JavascriptConversionExtensions.DictionarySupport(), JavascriptConversionExtensions.LinqMethodsSupport.Instance, new JavascriptConversionExtensions.ConstSupport(conventions), JavascriptConversionExtensions.ToStringSupport.Instance, JavascriptConversionExtensions.DateTimeSupport.Instance, JavascriptConversionExtensions.TimeSpanSupport.Instance, JavascriptConversionExtensions.InvokeSupport.Instance, JavascriptConversionExtensions.NullCoalescingSupport.Instance, JavascriptConversionExtensions.StringSupport.Instance, JavascriptConversionExtensions.NestedConditionalSupport.Instance, new JavascriptConversionExtensions.ReplaceParameterWithNewName(project.Parameters[0], "doc"), new JavascriptConversionExtensions.IdentityPropertySupport(conventions), JavascriptConversionExtensions.CounterSupport.Instance, JavascriptConversionExtensions.CompareExchangeSupport.Instance, new JavascriptConversionExtensions.LoadSupport(), JavascriptConversionExtensions.MemberInit.Instance )); criteria.Query += Environment.NewLine + "select " + script; } if (includes != null) { var builder = new IncludeBuilder <T>(conventions); includes(builder); if (builder.DocumentsToInclude != null && builder.DocumentsToInclude.Count > 0) { criteria.Query += Environment.NewLine + "include "; var first = true; foreach (var inc in builder.DocumentsToInclude) { var include = "doc." + inc; if (first == false) { criteria.Query += ","; } first = false; if (IncludesUtil.RequiresQuotes(include, out var escapedInclude)) { criteria.Query += $"'{escapedInclude}'"; } else { criteria.Query += QueryToken.IsKeyword(include) ? $"'{include}'" : include; } } } } return(criteria); }