Class: Janeway::Query

Inherits:
Object
  • Object
show all
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

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)


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

#jsonpathString (readonly)

The original jsonpath query, for use in error messages

Returns:

  • (String)


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

def jsonpath
  @jsonpath
end

#rootAST::Root (readonly)

Returns:

  • (AST::Root)


13
14
15
# File 'lib/janeway/query.rb', line 13

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.



67
68
69
# File 'lib/janeway/query.rb', line 67

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

#dupQuery

Deep copy the query

Returns:



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.

Returns:



29
30
31
# File 'lib/janeway/query.rb', line 29

def enum_for(input)
  Janeway::Enumerator.new(self, input)
end

#node_listArray<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.

Returns:

  • (Array<Expression>)


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

#popAST::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.

Returns:



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.

Returns:

  • (Boolean)


42
43
44
# File 'lib/janeway/query.rb', line 42

def singular_query?
  @root.singular_query?
end

#to_sString

Returns:

  • (String)


34
35
36
# File 'lib/janeway/query.rb', line 34

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



73
74
75
76
77
# File 'lib/janeway/query.rb', line 73

def tree
  result = @root.tree(0)

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