Class: Janeway::AST::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/janeway/ast/query.rb

Overview

AST::Query holds the complete 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

Instance Method Summary collapse

Constructor Details

#initialize(root_node, jsonpath) ⇒ Query

Returns a new instance of Query.

Parameters:

  • root_node (AST::Root)
  • jsonpath (String)

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
# File 'lib/janeway/ast/query.rb', line 19

def initialize(root_node, jsonpath)
  raise ArgumentError, "expect root identifier, got #{root_node.inspect}" unless root_node.is_a?(RootNode)
  raise ArgumentError, "expect query string, got #{jsonpath.inspect}" unless jsonpath.is_a?(String)

  @root = root_node
  @jsonpath = jsonpath
end

Instance Attribute Details

#jsonpathString (readonly)

The original jsonpath query, for use in error messages

Returns:

  • (String)


15
16
17
# File 'lib/janeway/ast/query.rb', line 15

def jsonpath
  @jsonpath
end

#rootAST::RootNode (readonly)

Returns:



11
12
13
# File 'lib/janeway/ast/query.rb', line 11

def root
  @root
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.



85
86
87
# File 'lib/janeway/ast/query.rb', line 85

def ==(other)
  to_s == other.to_s
end

#each(input) {|matched| ... } ⇒ void

This method returns an undefined value.

Iterate through each value matched by the JSONPath query.

Parameters:

  • input (Hash, Array)

    ruby object to be searched

Yield Parameters:

  • matched (Object)

    value



40
41
42
43
44
45
46
# File 'lib/janeway/ast/query.rb', line 40

def each(input, &block)
  return enum_for(:each, input) unless block_given?

  interpreter = Janeway::Interpreter.new(self)
  interpreter.push Janeway::Interpreters::Yielder.new(&block)
  interpreter.interpret(input)
end

#find_all(input) ⇒ Array

Use this Query to search the input, and return the results.

Parameters:

  • input (Object)

    ruby object to be searched

Returns:

  • (Array)

    all matched objects



31
32
33
# File 'lib/janeway/ast/query.rb', line 31

def find_all(input)
  Janeway::Interpreter.new(self).interpret(input)
end

#node_listArray<Expression>

Return a list of all 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.

Returns:



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/janeway/ast/query.rb', line 56

def node_list
  nodes = []
  node = @root
  loop do
    nodes << node
    break unless node.next

    node = node.next
  end
  nodes
end

#popAST::Selector?

Remove the last selector in the query from the node list, and return the removed selector.

Returns:



70
71
72
73
74
75
76
77
78
# File 'lib/janeway/ast/query.rb', line 70

def pop
  nodes = node_list
  return nil if node_list.size == 1 # only 1 node, don't pop

  # Remove the last selector and return it
  last_node = nodes.pop
  nodes.last.next = nil # delete the second-last node's link to the last node
  last_node
end

#to_sObject



48
49
50
# File 'lib/janeway/ast/query.rb', line 48

def to_s
  @root.to_s
end

#treeObject

Print AST in tree format Every AST class prints a 1-line representation of self, with children on separate lines



91
92
93
94
95
# File 'lib/janeway/ast/query.rb', line 91

def tree
  result = @root.tree(0)

  result.flatten.join("\n")
end