Class: Janeway::Query
- Inherits:
-
Object
- Object
- Janeway::Query
- Defined in:
- lib/janeway/query.rb
Overview
Query holds the abstract syntax tree created by parsing the query. This can be frozen and passed to multiple threads or ractors for simultaneous use. No instance members are modified during the interpretation stage.
Instance Attribute Summary collapse
-
#jsonpath ⇒ String
readonly
The original jsonpath query, for use in error messages.
- #root ⇒ AST::Root readonly
Instance Method Summary collapse
-
#==(other) ⇒ Object
Queries are considered equal if their ASTs evaluate to the same JSONPath string.
-
#dup ⇒ Query
Deep copy the query.
-
#enum_for(input) ⇒ Janeway::Enumerator
Combine this query with input to make an Enumerator.
-
#initialize(root_node, jsonpath) ⇒ Query
constructor
A new instance of Query.
-
#node_list ⇒ Array<Expression>
Return a list of the nodes in the AST.
-
#pop ⇒ AST::Selector
Delete the last element from the chain of selectors.
-
#singular_query? ⇒ Boolean
Return true if this query can only possibly match 0 or 1 elements in any input.
- #to_s ⇒ String
-
#tree ⇒ Object
Print AST in tree format Every AST class prints a 1-line representation of self, with children on separate lines.
Constructor Details
#initialize(root_node, jsonpath) ⇒ Query
Returns a new instance of Query.
17 18 19 20 21 22 23 |
# File 'lib/janeway/query.rb', line 17 def initialize(root_node, jsonpath) raise ArgumentError, "expect root identifier, got #{root_node.inspect}" unless root_node.is_a?(AST::RootNode) raise ArgumentError, "expect query string, got #{jsonpath.inspect}" unless jsonpath.is_a?(String) @root = root_node @jsonpath = jsonpath end |
Instance Attribute Details
#jsonpath ⇒ String (readonly)
The original jsonpath query, for use in error messages
10 11 12 |
# File 'lib/janeway/query.rb', line 10 def jsonpath @jsonpath end |
Instance Method Details
#==(other) ⇒ Object
Queries are considered equal if their ASTs evaluate to the same JSONPath string.
The string output is generated from the AST and should be considered a “normalized” form of the query. It may have different whitespace and parentheses than the original input but will be semantically equivalent.
67 68 69 |
# File 'lib/janeway/query.rb', line 67 def ==(other) to_s == other.to_s end |
#dup ⇒ Query
Deep copy the query
81 82 83 |
# File 'lib/janeway/query.rb', line 81 def dup Parser.parse(to_s) end |
#enum_for(input) ⇒ Janeway::Enumerator
Combine this query with input to make an Enumerator. This can be used to iterate over results with #each, #map, etc.
29 30 31 |
# File 'lib/janeway/query.rb', line 29 def enum_for(input) Janeway::Enumerator.new(self, input) end |
#node_list ⇒ Array<Expression>
Return a list of the nodes in the AST. The AST of a jsonpath query is a straight line, so this is expressible as an array. The only part of the AST with branches is inside a filter selector, but that doesn’t show up here.
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/janeway/query.rb', line 50 def node_list nodes = [] node = @root loop do nodes << node break unless node.next node = node.next end nodes end |
#pop ⇒ AST::Selector
Delete the last element from the chain of selectors. For a singular query, this makes the query point to the match’s parent instead of the match itself.
Don’t do this for a non-singular query, those may contain child segments and descendant segments which would lead to different results.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/janeway/query.rb', line 92 def pop unless singular_query? raise Janeway::Error.new('not allowed to pop from a non-singular query', to_s) end # Sever the link to the last selector nodes = node_list if nodes.size == 1 # Special case: cannot pop from the query "$" even though it is a singular query raise Janeway::Error.new('cannot pop from single-element query', to_s) end nodes[-2].next = nil # Return the last selector nodes.last end |
#singular_query? ⇒ Boolean
Return true if this query can only possibly match 0 or 1 elements in any input. Such a query must be composed exclusively of the root identifier followed by name selectors and / or index selectors.
42 43 44 |
# File 'lib/janeway/query.rb', line 42 def singular_query? @root.singular_query? end |
#to_s ⇒ String
34 35 36 |
# File 'lib/janeway/query.rb', line 34 def to_s @root.to_s end |
#tree ⇒ Object
Print AST in tree format Every AST class prints a 1-line representation of self, with children on separate lines
73 74 75 76 77 |
# File 'lib/janeway/query.rb', line 73 def tree result = @root.tree(0) result.flatten.join("\n") end |