예제 #1
0
        private IGraphQueryStep BuildQueryPlanForMatchNode(MatchPath node)
        {
            var alias = node.Alias;

            if (GraphQuery.WithDocumentQueries.TryGetValue(alias, out var query) == false)
            {
                throw new InvalidOperationException($"BuildQueryPlanForMatchVertex was invoked for allias='{alias}' which is supposed to be a node but no corresponding WITH clause was found.");
            }
            // TODO: we can tell at this point if it is a collection query or not,
            // TODO: in the future, we want to build a diffrent step for collection queries in the future.
            var queryMetadata = new QueryMetadata(query.withQuery, _query.QueryParameters, 0, addSpatialProperties: false);
            var qqs           = new QueryQueryStep(_database.QueryRunner, alias, query.withQuery, queryMetadata, _query.QueryParameters, _context, _resultEtag, this, _token)
            {
                CollectIntermediateResults = CollectIntermediateResults
            };
            var key = qqs.GetQueryString;

            //We only want to cache queries that are not unique so we count them during their creation
            if (IdenticalQueriesCount.TryGetValue(key, out var count))
            {
                count.Value += 1;
            }
            else
            {
                IdenticalQueriesCount.Add(key, new Reference <int>()
                {
                    Value = 1
                });
            }

            return(qqs);
        }
예제 #2
0
        internal Match MapHtmlNodeToMatch(HtmlNode root, MatchPath matchPath, int currentCount)
        {
            Match match = new Match();

            match.Id = HtmlEntity.DeEntitize(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Id, currentCount)).Attributes[matchPath.IdAttribute].Value).Replace(matchPath.IdReplace, "");

            HtmlNode heroNode = root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Hero, currentCount));

            if (heroNode != null)
            {
                string heroReference = root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Hero, currentCount)).Attributes[HtmlAttributes.Hero.Attribute.Value].Value.Replace(HtmlAttributes.Hero.Replace.Value, "");
                match.Hero = mainController.HeroController.GetHero(heroReference);
            }

            match.Result  = mainController.MapStringToEnum <Results>(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Result, currentCount)).InnerText);
            match.TimeAgo = DateTime.Parse(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.TimeAgo, currentCount)).Attributes[MainController.HTML_ATTRIBUTE_DATETIME].Value);
            match.Type    = mainController.MapStringToEnum <Types>(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Type, currentCount)).InnerText);
            match.Mode    = mainController.MapStringToEnum <Modes>(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Mode, currentCount)).InnerText);

            HtmlNode skillBracketNode = root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Skillbracket, currentCount));

            if (skillBracketNode != null)
            {
                match.Skillbracket = mainController.MapStringToEnum <Skillbrackets>(HtmlEntity.DeEntitize(skillBracketNode.InnerText));
            }

            match.Duration = mainController.ConvertStringToTimeSpan(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Duration, currentCount)).InnerText);
            match.Kda      = mainController.ConvertStringToKda(root.SelectSingleNode(mainController.CombinePathWithListCount(matchPath.Kda, currentCount)).InnerText);
            return(match);
        }
예제 #3
0
        private void ThrowIfDuplicateAlias(MatchPath path)
        {
            if (path.Field != null)
            {
                if (_aliases.Contains(path.Alias) && !path.Alias.Equals(path.Field.FieldValue))
                {
                    var isImplicitAlias = false;
                    if (path.IsEdge && _query.WithEdgePredicates.TryGetValue(path.Alias, out var withEdge))
                    {
                        isImplicitAlias = withEdge.ImplicitAlias;
                    }
                    else if (_query.WithDocumentQueries.TryGetValue(path.Alias, out var withQuery))
                    {
                        isImplicitAlias = withQuery.implicitAlias;
                    }

                    if (isImplicitAlias)
                    {
                        throw new InvalidQueryException($"Found redefinition of an implicit alias '{path.Alias}', this is not allowed. Note: If you specify nodes or edges without an alias, for example like this: '(Employees)', then implicit alias will be generated. ", _query.QueryText);
                    }

                    throw new InvalidQueryException($"Found redefinition of alias '{path.Alias}', this is not allowed. The correct syntax is to have only single alias definition in the form of '(Employees as e)'", _query.QueryText);
                }

                _aliases.Add(path.Alias);
            }
            else if (!_aliases.Contains(path.Alias) && !_query.WithDocumentQueries.ContainsKey(path.Alias) && !_query.WithEdgePredicates.ContainsKey(path.Alias))
            {
                throw new InvalidQueryException($"Found duplicate alias '{path.Alias}', this is not allowed", _query.QueryText);
            }
        }
예제 #4
0
        internal List <Match> FetchLatestMatches(string playerId)
        {
            HtmlNode root = mainController.HtmlDocumentController.GetDotabuffPlayerRoot(playerId);

            IEnumerable <HtmlNode> latestMatches = root.SelectNodes(PlayerPath.LatestMatches.List.Value);

            List <Match> matchList = new List <Match>();

            MatchPath matchPath = new MatchPath
            {
                Duration     = PlayerPath.LatestMatches.Duration.Value,
                Hero         = PlayerPath.LatestMatches.Hero.Value,
                Id           = PlayerPath.LatestMatches.Id.Value,
                Kda          = PlayerPath.LatestMatches.Kda.Value,
                Mode         = PlayerPath.LatestMatches.Mode.Value,
                Result       = PlayerPath.LatestMatches.Result.Value,
                Skillbracket = PlayerPath.LatestMatches.Skillbracket.Value,
                TimeAgo      = PlayerPath.LatestMatches.TimeAgo.Value,
                Type         = PlayerPath.LatestMatches.Type.Value,
                IdAttribute  = HtmlAttributes.Match.Attribute.Value,
                IdReplace    = HtmlAttributes.Match.Replace.Value
            };

            for (int i = 1; i < latestMatches.Count() + 1; i++)
            {
                Match match = MapHtmlNodeToMatch(root, matchPath, i);
                matchList.Add(match);
            }

            return(matchList);
        }
예제 #5
0
        internal IEnumerable <IMatchExtended> GetMatchesFromPlayer(string playerId, PlayerMatchesOptions playerMatchesOptions)
        {
            HtmlNode root = mainController.HtmlDocumentController.GetDotabuffPlayerMatchesRoot(playerId, playerMatchesOptions);

            List <IMatchExtended> playerMatches = new List <IMatchExtended>();

            MatchPath machPath = new MatchPath
            {
                Duration     = PlayerMatchesPath.Duration.Value,
                Hero         = PlayerMatchesPath.Hero.Value,
                Id           = PlayerMatchesPath.Id.Value,
                Kda          = PlayerMatchesPath.Kda.Value,
                Mode         = PlayerMatchesPath.Mode.Value,
                Result       = PlayerMatchesPath.Result.Value,
                Skillbracket = PlayerMatchesPath.Skillbracket.Value,
                TimeAgo      = PlayerMatchesPath.TimeAgo.Value,
                Type         = PlayerMatchesPath.Type.Value,
                IdAttribute  = HtmlAttributes.PlayerMatches.Attribute.Value,
                IdReplace    = HtmlAttributes.PlayerMatches.Replace.Value,
            };

            int counter = 1;
            IEnumerable <HtmlNode> matchesNodes = root.SelectNodes(PlayerMatchesPath.Table.Value);

            if (matchesNodes != null)
            {
                foreach (HtmlNode matchNode in matchesNodes)
                {
                    Match match = matchController.MapHtmlNodeToMatch(root, machPath, counter);

                    List <IItem>           items     = new List <IItem>();
                    IEnumerable <HtmlNode> itemNodes = root.SelectNodes(mainController.CombinePathWithListCount(PlayerMatchesPath.Items.Value, counter));

                    if (itemNodes != null)
                    {
                        foreach (HtmlNode itemNode in itemNodes)
                        {
                            string itemReference =
                                itemNode.Attributes[HtmlAttributes.Item.Attribute.Value].Value.Replace(
                                    HtmlAttributes.Item.Replace.Value, "");
                            items.Add(mainController.ItemController.GetItem(itemReference));
                        }
                    }

                    match.Items = items;

                    playerMatches.Add(match);

                    counter++;
                }
            }

            return(playerMatches);
        }
예제 #6
0
        public EdgeQueryStep(IGraphQueryStep left, IGraphQueryStep right, WithEdgesExpression edgesExpression, MatchPath edgePath, BlittableJsonReaderObject queryParameters, OperationCancelToken token)
        {
            _left  = left;
            _right = right;

            _aliases = new HashSet <string>();

            _aliases.UnionWith(_left.GetAllAliases());
            _aliases.UnionWith(_right.GetAllAliases());
            _aliases.Add(edgePath.Alias.Value);

            _edgePath        = edgePath;
            _queryParameters = queryParameters;
            _edgesExpression = edgesExpression;

            _outputAlias = _right.GetOutputAlias();
            _token       = token;
        }
예제 #7
0
        private IGraphQueryStep BuildQueryPlanForEdge(IGraphQueryStep left, IGraphQueryStep right, MatchPath edge)
        {
            var alias = edge.Alias;

            if (GraphQuery.WithEdgePredicates.TryGetValue(alias, out var withEdge) == false)
            {
                throw new InvalidOperationException($"BuildQueryPlanForEdge was invoked for alias='{alias}' which suppose to be an edge but no corresponding WITH EDGE clause was found.");
            }

            return(new EdgeQueryStep(left, right, withEdge, edge, _query.QueryParameters, _token)
            {
                CollectIntermediateResults = CollectIntermediateResults
            });
        }
예제 #8
0
 private static void ThrowExpectedEdgeButFoundRecursive(MatchPath patternMatchElement, PatternMatchElementExpression elementExpression)
 {
     throw new InvalidQueryException($"Invalid pattern match syntax: expected element '{patternMatchElement}' to be of type edge, but it is a recursive clause. In a graph query, recursive clause is considered an edge, and should be preceded by a vertex and superseded by edge. (The full expression: '{elementExpression}')");
 }
예제 #9
0
 private static void ThrowExpectedEdgeButFoundVertex(MatchPath patternMatchElement, PatternMatchElementExpression elementExpression)
 {
     throw new InvalidQueryException($"Invalid pattern match syntax: expected element '{patternMatchElement}' to be of type edge, but it is an vertex. (The full expression: '{elementExpression}')");
 }
예제 #10
0
 private static QueryStepElementType DetermineEdgeOrVertex(MatchPath patternMatchElement) => patternMatchElement.IsEdge ? QueryStepElementType.Edge : QueryStepElementType.Vertex;