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); }
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); }
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); } }
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); }
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); }
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; }
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 }); }
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}')"); }
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}')"); }
private static QueryStepElementType DetermineEdgeOrVertex(MatchPath patternMatchElement) => patternMatchElement.IsEdge ? QueryStepElementType.Edge : QueryStepElementType.Vertex;