Ejemplo n.º 1
0
        public void UpdateNode(SearchExpressionNode ex)
        {
            if (!TryGetNode(ex, out var node))
            {
                return;
            }

            node.title = FormatTitle(ex);

            if (ex.color != Color.clear)
            {
                node.titleContainer.style.backgroundColor = ex.color;
            }

            // Update result port
            if (ex.type == ExpressionType.Value ||
                ex.type == ExpressionType.Provider)
            {
                var outputPort = FindPort(node, "output");
                if (outputPort != null)
                {
                    outputPort.portName = Convert.ToString(ex.value);
                }
            }
            else if (ex.type == ExpressionType.Union)
            {
                UpdateUnionVariables(node);
            }
            else if (ex.type == ExpressionType.Select)
            {
                var outputPort = FindPort(node, "output");
                if (outputPort != null)
                {
                    outputPort.portName = GetSelectNodeOutputPortName(ex);
                }
            }
            else if (ex.type == ExpressionType.Map)
            {
                if (ex.TryGetVariableSource(ExpressionKeyName.X, out var xSource))
                {
                    if (!ex.TryGetProperty(ExpressionKeyName.GroupBy, out string groupBy) || string.IsNullOrEmpty(groupBy))
                    {
                        ex.SetProperty(ExpressionKeyName.GroupBy, GetSelectNodeOutputPortName(xSource).ToLowerInvariant());
                    }
                }

                if (ex.TryGetVariableSource(ExpressionKeyName.Y, out var ySource) && xSource == ySource)
                {
                    ex.SetProperty(nameof(Mapping), (int)Mapping.Table);
                }
            }

            NotifyGraphChanged();
        }
Ejemplo n.º 2
0
        private void DrawMapEditor()
        {
            var mapping = (Mapping)m_Node.GetProperty(nameof(Mapping), (int)Mapping.Count);
            var groupBy = m_Node.GetProperty(ExpressionKeyName.GroupBy, "");

            EditorGUI.BeginChangeCheck();
            mapping = (Mapping)EditorGUILayout.EnumPopup(nameof(Mapping), mapping);
            if (m_Node.TryGetVariableSource(ExpressionKeyName.X, out var xSource) && xSource != null && mapping != Mapping.Table)
            {
                groupBy = EditorGUILayout.DelayedTextField("Group By", groupBy);
            }
            else
            {
                GUILayout.Space(20);
            }
            if (EditorGUI.EndChangeCheck())
            {
                m_Node.SetProperty(nameof(Mapping), (int)mapping);
                m_Node.SetProperty(ExpressionKeyName.GroupBy, groupBy);
                propertiesChanged?.Invoke(m_Node);
            }
        }
Ejemplo n.º 3
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.º 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);