Class: Gitlab::Graphql::QueryAnalyzers::AST::RecursionAnalyzer
- Inherits:
-
GraphQL::Analysis::AST::Analyzer
- Object
- GraphQL::Analysis::AST::Analyzer
- Gitlab::Graphql::QueryAnalyzers::AST::RecursionAnalyzer
- Defined in:
- lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer.rb
Constant Summary collapse
- IGNORED_FIELDS =
%w[node edges nodes ofType].freeze
- RECURSION_THRESHOLD =
2
Instance Method Summary collapse
-
#initialize(query) ⇒ RecursionAnalyzer
constructor
A new instance of RecursionAnalyzer.
- #on_enter_field(node, _parent, visitor) ⇒ Object
-
#on_leave_field(node, _parent, visitor) ⇒ Object
Visitors are all defined on the AST::Analyzer base class We override them for custom analyzers.
- #result ⇒ Object
Constructor Details
#initialize(query) ⇒ RecursionAnalyzer
Returns a new instance of RecursionAnalyzer.
13 14 15 16 17 18 |
# File 'lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer.rb', line 13 def initialize(query) super @node_visits = {} @recurring_fields = {} end |
Instance Method Details
#on_enter_field(node, _parent, visitor) ⇒ Object
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer.rb', line 20 def on_enter_field(node, _parent, visitor) return if skip_node?(node, visitor) node_name = node.name node_visits[node_name] ||= 0 node_visits[node_name] += 1 times_encountered = @node_visits[node_name] recurring_fields[node_name] = times_encountered if recursion_too_deep?(node_name, times_encountered) end |
#on_leave_field(node, _parent, visitor) ⇒ Object
Visitors are all defined on the AST::Analyzer base class We override them for custom analyzers.
33 34 35 36 37 38 39 |
# File 'lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer.rb', line 33 def on_leave_field(node, _parent, visitor) return if skip_node?(node, visitor) node_name = node.name node_visits[node_name] ||= 0 node_visits[node_name] -= 1 end |
#result ⇒ Object
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer.rb', line 41 def result @recurring_fields = @recurring_fields.select { |k, v| recursion_too_deep?(k, v) } if @recurring_fields.any? GraphQL::AnalysisError.new(<<~MSG) Recursive query - too many of fields '#{@recurring_fields}' detected in single branch of the query") MSG end end |