Ejemplo n.º 1
0
        private SearchRequest BuildUnionRequest(SearchExpressionNode ex)
        {
            if (ex.variables == null)
            {
                return(null);
            }

            if (ex.variables == null)
            {
                return(null);
            }

            var unionItems   = new HashSet <SearchItem>();
            var unionRequest = new SearchRequest(ex.type);

            foreach (var v in ex.variables)
            {
                if (v.source != null)
                {
                    var sourceRequest = BuildRequest(v.source);
                    unionRequest.DependsOn(sourceRequest);

                    sourceRequest.Resolve(results => unionItems.UnionWith(results), null);
                }
            }

            unionRequest.resolved += exs => unionRequest.ProcessItems(exs.context, unionItems);
            return(unionRequest);
        }
Ejemplo n.º 2
0
        private SearchRequest BuildTwoSetRequest(SearchExpressionNode ex, Func <IList <SearchItem>, IList <SearchItem>, IEnumerable <SearchItem> > transformer)
        {
            if (ex.variables == null)
            {
                return(null);
            }

            var exSearch = new SearchRequest(ex.type);

            if (ex.source != null && ex.TryGetVariableSource("With", out var withSource) && withSource != null)
            {
                var sourceExpression = BuildRequest(ex.source);
                var withExpression   = BuildRequest(withSource);

                exSearch.DependsOn(sourceExpression);
                exSearch.DependsOn(withExpression);

                bool fetchSourceItemsFinished = false;
                bool fetchWithItemsFinished   = false;
                var  sourceItems = new List <SearchItem>();
                var  withItems   = new List <SearchItem>();

                sourceExpression.Resolve(results => sourceItems.AddRange(results), exs => fetchSourceItemsFinished = true);
                withExpression.Resolve(results => withItems.AddRange(results), exs => fetchWithItemsFinished       = true);

                exSearch.resolved += exs =>
                {
                    if (fetchSourceItemsFinished && fetchWithItemsFinished)
                    {
                        exSearch.ProcessItems(null, transformer(sourceItems, withItems));
                    }
                };
            }

            return(exSearch);
        }
Ejemplo n.º 3
0
        private SearchRequest BuildSearchRequest(SearchExpressionNode node)
        {
            var dynamicVariables = new List <ExpressionVariable>();
            var searchQuery      = Convert.ToString(node.value);

            if (node.variables != null)
            {
                foreach (var v in node.variables)
                {
                    if (v.source != null)
                    {
                        dynamicVariables.Add(v);
                    }
                }
            }

            if (dynamicVariables.Count == 0)
            {
                return(BuildFromSearchQuery(node, searchQuery));
            }

            var req = new SearchRequest(node.type);
            var varFetchResolved = new Dictionary <string, bool>();
            var varResults       = new Dictionary <string, HashSet <string> >();

            foreach (var v in dynamicVariables)
            {
                varFetchResolved[v.name] = false;
            }

            foreach (var v in dynamicVariables)
            {
                var varName    = v.name;
                var varRequest = BuildRequest(v.source);

                req.DependsOn(varRequest);
                varRequest.Resolve(items =>
                {
                    if (!varResults.TryGetValue(varName, out var results))
                    {
                        results             = new HashSet <string>();
                        varResults[varName] = results;
                    }

                    results.UnionWith(items.Select(i => i.id));
                }, r =>
                {
                    varFetchResolved[varName] = true;

                    if (varFetchResolved.All(kvp => kvp.Value))
                    {
                        var totalRequest = 1;
                        foreach (var vrs in varResults)
                        {
                            if (vrs.Value.Count == 0)
                            {
                                continue;
                            }
                            totalRequest *= vrs.Value.Count;
                        }

                        var queries = new string[totalRequest];
                        for (int i = 0; i < totalRequest; ++i)
                        {
                            queries[i] = searchQuery;
                        }

                        foreach (var vrs in varResults)
                        {
                            if (vrs.Value.Count == 0)
                            {
                                continue;
                            }

                            for (int i = 0; i < totalRequest;)
                            {
                                foreach (var varValue in vrs.Value)
                                {
                                    queries[i] = queries[i].Replace($"${vrs.Key}", varValue);
                                    ++i;
                                }
                            }
                        }

                        requestCount += totalRequest;
                        foreach (var q in queries)
                        {
                            BuildFromSearchQuery(node, q).TransferTo(req);
                        }
                    }
                });
            }

            return(req);
        }
Ejemplo n.º 4
0
        private SearchRequest BuildMappingRequest(SearchExpressionNode node)
        {
            var mapping = (Mapping)node.GetProperty(nameof(Mapping), (int)Mapping.Count);
            var groupBy = node.GetProperty(ExpressionKeyName.GroupBy, "");

            if (node.TryGetVariableSource(ExpressionKeyName.X, out var xSource) && String.IsNullOrWhiteSpace(groupBy))
            {
                Debug.LogWarning($"Group by {mapping} mapping not defined for {node.name ?? node.id}.");
                return(SearchRequest.empty);
            }

            var grouping = xSource != null;

            if (!node.TryGetVariableSource(ExpressionKeyName.Y, out var ySource))
            {
                Debug.LogWarning($"No data source (Y) set for {node.name ?? node.id}.");
                return(SearchRequest.empty);
            }
            else if (grouping && ySource.type == ExpressionType.Select && !ySource.GetProperty(ExpressionKeyName.Mapped, false))
            {
                Debug.LogWarning($"Mapping data source for {node.name ?? node.id} must be a search node (currently a {ySource.type} node)");
                if (ySource.source?.type == ExpressionType.Search)
                {
                    ySource = ySource.source;
                }
            }

            var mappingRequest = new SearchRequest(node.type);

            if (mapping == Mapping.Table)
            {
                if (xSource == null)
                {
                    Debug.LogWarning($"No data source (X) set for {node.name ?? node.id}.");
                    return(SearchRequest.empty);
                }

                var xRequest = BuildRequest(xSource);
                var yRequest = BuildRequest(ySource);

                mappingRequest.DependsOn(xRequest);
                mappingRequest.DependsOn(yRequest);

                bool fetchSourceX = false;
                var  xItems       = new List <SearchItem>();
                xRequest.Resolve(results => xItems.AddRange(results), exs => fetchSourceX = true);

                bool fetchSourceY = false;
                var  yItems       = new List <SearchItem>();
                yRequest.Resolve(results => yItems.AddRange(results), exs => fetchSourceY = true);

                mappingRequest.resolved += _ =>
                {
                    if (!fetchSourceX || !fetchSourceY)
                    {
                        throw new ExpressionException(node, "Table mapping wasn't resolved properly");
                    }

                    int xIndex = 0;
                    foreach (var x in xItems)
                    {
                        var y = yItems.Count >= 0 && xIndex < yItems.Count ? yItems[xIndex].value : null;
                        if (y != null && !(y is double) && double.TryParse(y.ToString(), out var d))
                        {
                            y = d;
                        }
                        x.value = new MappingData()
                        {
                            type  = Mapping.Table,
                            value = y,
                            query = xSource.GetProperty(ExpressionKeyName.BakedQuery, x.context?.searchQuery)
                        };
                        x.description = $"{y}";
                        ++xIndex;
                    }
                    mappingRequest.ProcessItems(xItems);
                };
            }
            else
            {
                var groupsRequest = BuildRequest(xSource ?? new SearchExpressionNode(ExpressionType.Value, null, ""));
                var groups        = new Dictionary <string, List <object> >();
                mappingRequest.DependsOn(groupsRequest);
                groupsRequest.Resolve(items =>
                {
                    foreach (var item in items)
                    {
                        var groupName   = grouping ? item.id : node.name ?? mapping.ToString();
                        var groupQuery  = grouping ? $"({ySource.value}) {groupBy}={groupName}" : ySource.value as string;
                        var groupSource = grouping ? new SearchExpressionNode(ySource.type, ySource.source, groupQuery, ySource.variables) : ySource;

                        var groupRequest = BuildRequest(groupSource);
                        mappingRequest.DependsOn(groupRequest);
                        groupsRequest.DependsOn(groupRequest);

                        if (!groups.ContainsKey(groupName))
                        {
                            groups[groupName] = new List <object>();
                        }

                        var groupData  = groups[groupName];
                        var totalCount = 0.0;
                        var totalValue = 0.0;

                        groupRequest.Resolve(groupItems =>
                        {
                            switch (mapping)
                            {
                            case Mapping.Min: UpdateMappingMin(groupData, groupItems); break;

                            case Mapping.Max: UpdateMappingMax(groupData, groupItems); break;

                            case Mapping.Average: UpdateMappingAverage(groupData, groupItems, ref totalCount, ref totalValue); break;

                            case Mapping.Count: UpdateMappingCount(groupData, groupItems); break;
                            }
                        }, _ =>
                        {
                            mappingRequest.ProcessItems(groupData.OrderBy(e => e).Select(e => new SearchItem(xSource == null ? e?.ToString() : groupName)
                            {
                                score       = double.TryParse(groupName, out var d) ? -(int)d : groupName.GetHashCode(),
                                label       = groupName,
                                description = e?.ToString(),
                                value       = new MappingData()
                                {
                                    type = mapping, value = e, query = groupSource.GetProperty(ExpressionKeyName.BakedQuery, groupQuery)
                                }
                            }));
                        });
                    }
                }, null);