public static IEnumerable <SearchItem> GroupBy(SearchExpressionContext c) { string selector = null; if (c.args.Length > 1) { selector = c.args[1].innerText.ToString(); } var outputValueFieldName = System.Guid.NewGuid().ToString("N"); var dataSet = SelectorManager.SelectValues(c.search, c.args[0].Execute(c), selector, outputValueFieldName); foreach (var _group in dataSet.GroupBy(item => item.GetValue(outputValueFieldName))) { var group = _group; var groupId = group.Key?.ToString() ?? $"group{++s_NextGroupId}"; if (c.HasFlag(SearchExpressionExecutionFlags.Expand)) { var evaluator = new SearchExpressionEvaluator(groupId, _ => group, SearchExpressionEvaluationHints.Default); var genExpr = new SearchExpression(SearchExpressionType.Group, groupId.GetStringView(), groupId.GetStringView(), (group.Key?.ToString() ?? groupId).GetStringView(), evaluator); yield return(EvaluatorUtils.CreateSearchExpressionItem(genExpr)); } else { SearchProvider groupProvider = null; foreach (var item in group) { if (groupProvider == null) { groupProvider = SearchUtils.CreateGroupProvider(item.provider, groupId, s_NextGroupId); } item.provider = groupProvider; yield return(item); } } } }
public static IEnumerable <SearchItem> Alias(SearchExpressionContext c) { var aliasSelector = c.args.Last(); if (c.HasFlag(SearchExpressionExecutionFlags.Expand)) { yield return(EvaluatorUtils.CreateSearchExpressionItem(new SearchExpression(c.args[0], newAlias: aliasSelector.innerText))); } else { foreach (var r in c.args[0].Execute(c)) { if (r == null) { yield return(null); continue; } var hasFormatString = EvaluatorUtils.GetFormatString(aliasSelector, out var formatStr); if (hasFormatString && aliasSelector.types.HasAny(SearchExpressionType.Text)) { r.label = EvaluatorUtils.FormatItem(c.search, r, formatStr); } else if (aliasSelector.types.HasAny(SearchExpressionType.Selector)) { r.label = SelectorManager.SelectValue(r, c.search, aliasSelector.innerText.ToString()).ToString(); yield return(r); } else if (aliasSelector.types.HasAny(SearchExpressionType.Iterable)) { bool valueSelected = false; using (c.runtime.Push(r)) { foreach (var s in aliasSelector.Execute(c)) { if (s != null) { r.label = s.value.ToString(); valueSelected = true; break; } else { yield return(null); } } } if (!valueSelected) { r.label = r.label = EvaluatorUtils.FormatItem(c.search, r, aliasSelector.innerText.ToString()); } } else { c.ThrowError($"Alias selector `{aliasSelector.outerText}` not supported", aliasSelector.outerText); } yield return(r); } } }
private IEnumerable <SearchItem> Evaluate(SearchExpressionContext c, SearchExpressionExecutionFlags flags) { var args = new List <SearchExpression>(); foreach (var p in parameters) { var evalHints = p.evaluator.hints; if (evalHints.HasFlag(SearchExpressionEvaluationHints.AlwaysExpand) || (p.types.HasFlag(SearchExpressionType.Expandable) && evalHints.HasFlag(SearchExpressionEvaluationHints.ExpandSupported))) { foreach (var exprItem in p.Execute(c, SearchExpressionExecutionFlags.Expand)) { if (exprItem != null) { if (exprItem.data is SearchExpression expr) { args.Add(expr); } else { c.ThrowError($"cannot expand {p}"); } } else { yield return(null); } } } else if (p.types.HasFlag(SearchExpressionType.Expandable)) { foreach (var exprItem in p.Execute(c)) { if (exprItem == null) { yield return(null); continue; } if (exprItem.value != null) { if (Utils.TryGetNumber(exprItem.value, out var d)) { args.Add(new SearchExpression(SearchExpressionType.Number, d.ToString().GetStringView(), Parsers.ConstantEvaluator)); } else if (exprItem.value is string s) { args.Add(new SearchExpression(SearchExpressionType.Text, s.GetStringView(), Parsers.ConstantEvaluator)); } else { c.ThrowError("Cannot expand parameters"); } } else { c.ThrowError("Cannot expand null value"); } } } else { args.Add(p); } } using (c.runtime.Push(this, args, flags)) { var skipNull = c.HasFlag(SearchExpressionExecutionFlags.ThreadedEvaluation) && !c.HasFlag(SearchExpressionExecutionFlags.PassNull); var executeContext = c.runtime.current; var timeoutWatch = new System.Diagnostics.Stopwatch(); timeoutWatch.Start(); foreach (var r in evaluator.execute(executeContext)) { if (r != null) { timeoutWatch.Restart(); yield return(r); } else if (!skipNull) { if (timeoutWatch.Elapsed.TotalSeconds > 3.0d) { c.ThrowError("Timeout"); } yield return(null); } } } }