pacer 1.0.3-java → 1.1.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/Gemfile +1 -6
  2. data/lib/{pacer-1.0.3-standalone.jar → pacer-1.1.0-standalone.jar} +0 -0
  3. data/lib/pacer.rb +4 -0
  4. data/lib/pacer/blueprints/payload_elements.rb +44 -0
  5. data/lib/pacer/core/graph.rb +1 -0
  6. data/lib/pacer/core/graph/element_route.rb +3 -2
  7. data/lib/pacer/core/graph/path_route.rb +138 -0
  8. data/lib/pacer/core/route.rb +145 -1
  9. data/lib/pacer/filter/empty_filter.rb +2 -0
  10. data/lib/pacer/filter/loop_filter.rb +85 -0
  11. data/lib/pacer/filter/property_filter/filters.rb +6 -1
  12. data/lib/pacer/graph/graph_transactions_mixin.rb +6 -1
  13. data/lib/pacer/graph/pacer_graph.rb +47 -30
  14. data/lib/pacer/graph/yaml_encoder.rb +2 -0
  15. data/lib/pacer/loader.rb +9 -0
  16. data/lib/pacer/pipe/block_filter_pipe.rb +3 -2
  17. data/lib/pacer/pipe/loop_pipe.rb +23 -17
  18. data/lib/pacer/pipe/multi_pipe.rb +40 -0
  19. data/lib/pacer/pipe/naked_pipe.rb +21 -0
  20. data/lib/pacer/pipe/unwrapping_pipe.rb +4 -0
  21. data/lib/pacer/pipe/wrapping_pipe.rb +4 -0
  22. data/lib/pacer/pipes.rb +2 -1
  23. data/lib/pacer/route/mixin/route_operations.rb +15 -0
  24. data/lib/pacer/route_builder.rb +8 -11
  25. data/lib/pacer/side_effect/counted.rb +1 -0
  26. data/lib/pacer/side_effect/group_count.rb +1 -1
  27. data/lib/pacer/support/array.rb +18 -0
  28. data/lib/pacer/support/enumerable.rb +4 -0
  29. data/lib/pacer/transform/cap.rb +31 -0
  30. data/lib/pacer/transform/flat_map.rb +9 -0
  31. data/lib/pacer/transform/make_pairs.rb +29 -0
  32. data/lib/pacer/transform/map.rb +50 -2
  33. data/lib/pacer/transform/path.rb +27 -42
  34. data/lib/pacer/transform/path_tree.rb +111 -0
  35. data/lib/pacer/transform/payload.rb +50 -0
  36. data/lib/pacer/transform/process.rb +15 -0
  37. data/lib/pacer/transform/wrapped_path.rb +23 -0
  38. data/lib/pacer/utils/graph_analysis.rb +21 -7
  39. data/lib/pacer/version.rb +1 -1
  40. data/lib/pacer/wrappers/edge_wrapper.rb +18 -7
  41. data/lib/pacer/wrappers/element_wrapper.rb +4 -0
  42. data/lib/pacer/wrappers/index_wrapper.rb +1 -1
  43. data/lib/pacer/wrappers/path_wrapping_pipe_function.rb +85 -0
  44. data/lib/pacer/wrappers/vertex_wrapper.rb +33 -3
  45. data/pom.xml +1 -1
  46. data/spec/pacer/filter/property_filter/edge_filters_spec.rb +63 -0
  47. data/spec/pacer/filter/property_filter/filters_spec.rb +17 -7
  48. data/spec/pacer/transform/join_spec.rb +0 -1
  49. data/spec/pacer/transform/path_tree_spec.rb +97 -0
  50. data/spec/spec_helper.rb +2 -2
  51. metadata +18 -3
@@ -11,6 +11,21 @@ module Pacer
11
11
  module Process
12
12
  attr_accessor :block
13
13
 
14
+ def help(section = nil)
15
+ case section
16
+ when nil
17
+ puts <<HELP
18
+ The process method executes the given block for each element that is
19
+ passed through the route. After the block is called, the element that
20
+ was passed to it is emitted to be handled by the next step in the route.
21
+
22
+ It is Pacer's lazy version of the #each method.
23
+
24
+ HELP
25
+ else
26
+ super
27
+ end
28
+ end
14
29
  protected
15
30
 
16
31
  def attach_pipe(end_pipe)
@@ -0,0 +1,23 @@
1
+ module Pacer
2
+ module Core
3
+ module Graph
4
+ module PathRoute
5
+ def wrapped(*exts)
6
+ chain_route transform: :wrap_path, element_type: :path
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ module Transform
13
+ module WrapPath
14
+ protected
15
+
16
+ def attach_pipe(end_pipe)
17
+ pipe = Pacer::Pipes::PathWrappingPipe.new(graph)
18
+ pipe.setStarts end_pipe
19
+ pipe
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,14 +8,28 @@ module Pacer
8
8
  def structure(graph, type_field = :type)
9
9
  result = Pacer.tg
10
10
  result.vertex_name = proc do |v|
11
- if v[:element_type] == 'vertex'
12
- "vertex '#{v[:type]}' (#{v[:count]})"
13
- elsif v[:element_type] == 'edge'
14
- "edge :#{v[:label]} (#{v[:count]})"
15
- elsif v[:element_type] == 'property keys'
16
- "properties #{v[:number]} keys (#{v[:count]})"
11
+ case v[:element_type]
12
+ when 'vertex'
13
+ "vertex '#{ v[:type] }' (#{ v[:count] })"
14
+ when 'edge'
15
+ "edge '#{ v[:label] }' (#{ v[:count] })"
16
+ when 'property keys'
17
+ if v[:keys].empty?
18
+ "has no properties"
19
+ else
20
+ "has properties: #{ v[:keys].join ', ' } (#{ v[:count] })"
21
+ end
22
+ end
23
+ end
24
+ result.edge_name = proc do |e|
25
+ if e.label == 'properties'
26
+ "#{ e[:count] }"
27
+ else
28
+ "#{ e[:count] } '#{ e.label }' edges to"
17
29
  end
18
30
  end
31
+
32
+
19
33
  graph.v[type_field].fast_group_count.to_h.each do |type, count|
20
34
  result.create_vertex :element_type => 'vertex', :type_field => type_field, :type => type, :count => count
21
35
  end
@@ -28,7 +42,7 @@ module Pacer
28
42
  end
29
43
  result.v(:element_type => 'edge').each do |edge_node|
30
44
  puts "edges with label #{ edge_node[:label] }: #{ edge_node[:count] }"
31
- edge_route = graph.e(self, edge_node[:label])
45
+ edge_route = graph.e(edge_node[:label]).e(self)
32
46
  edge_route.property_variations result, edge_node
33
47
  end
34
48
  result.v.each do |type_node|
data/lib/pacer/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Pacer
2
2
  unless const_defined? :VERSION
3
- VERSION = "1.0.3"
3
+ VERSION = "1.1.0"
4
4
 
5
5
  JAR = "pacer-#{ VERSION }-standalone.jar"
6
6
  JAR_PATH = "lib/#{ JAR }"
@@ -4,9 +4,12 @@ module Pacer::Wrappers
4
4
  include Pacer::Core::Graph::EdgesRoute
5
5
 
6
6
  def_delegators :@element,
7
- :getId, :getLabel, :getPropertyKeys, :getProperty, :setProperty, :removeProperty,
8
- :getVertex,
9
- :getRawEdge
7
+ # Object
8
+ :equals, :toString, :hashCode,
9
+ # Element
10
+ :getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty, :getRawElement,
11
+ # Edge
12
+ :getLabel, :getVertex, :getRawEdge
10
13
 
11
14
  class << self
12
15
  def wrappers
@@ -128,7 +131,7 @@ module Pacer::Wrappers
128
131
  # @yield [e] Optional block yields the edge after it has been created.
129
132
  # @return [Pacer::Wrappers::EdgeWrapper] the new edge
130
133
  #
131
- # @raise [StandardError] If this the associated vertices don't exist and :create_vertices is not set
134
+ # @raise [Pacer::ElementNotFound] If this the associated vertices don't exist and :create_vertices is not set
132
135
  def clone_into(target_graph, opts = {})
133
136
  e_idx = target_graph.temp_index("tmp-e-#{graph.graph_id}", :edge, :create => true)
134
137
  e = e_idx.first('id', element_id)
@@ -143,7 +146,7 @@ module Pacer::Wrappers
143
146
  if not iv or not ov
144
147
  message = "Vertex not found for #{ self.inspect }: #{ iv.inspect } -> #{ ov.inspect }"
145
148
  puts message if opts[:show_missing_vertices]
146
- raise message unless opts[:ignore_missing_vertices]
149
+ fail Pacer::ElementNotFound, message unless opts[:ignore_missing_vertices]
147
150
  return nil
148
151
  end
149
152
  e = target_graph.create_edge(element_id, ov, iv, label, properties)
@@ -160,13 +163,13 @@ module Pacer::Wrappers
160
163
  # @yield [e] Optional block yields the edge after it has been created.
161
164
  # @return [Pacer::Wrappers::EdgeWrapper] the new edge
162
165
  #
163
- # @raise [StandardError] If this the associated vertices don't exist
166
+ # @raise [Pacer::ElementNotFound] If this the associated vertices don't exist
164
167
  def copy_into(target_graph)
165
168
  v_idx = target_graph.temp_index("tmp-v-#{graph.graph_id}", :vertex, :create => true)
166
169
  iv = v_idx.first('id', in_vertex.element_id) || target_graph.vertex(in_vertex.element_id)
167
170
  ov = v_idx.first('id', out_vertex.element_id) || target_graph.vertex(out_vertex.element_id)
168
171
 
169
- raise 'vertices not found' if not iv or not ov
172
+ fail Pacer::ElementNotFound 'vertices not found' if not iv or not ov
170
173
  e = target_graph.create_edge nil, ov, iv, label, properties
171
174
  yield e if block_given?
172
175
  e
@@ -197,5 +200,13 @@ module Pacer::Wrappers
197
200
  def hash
198
201
  -element.hash
199
202
  end
203
+
204
+ def element_payload=(data)
205
+ if element.is_a? Pacer::Payload::Edge
206
+ element.payload = data
207
+ else
208
+ @element = Pacer::Payload::Edge.new element, data
209
+ end
210
+ end
200
211
  end
201
212
  end
@@ -160,6 +160,10 @@ module Pacer::Wrappers
160
160
  display_name.to_s <=> other.display_name.to_s
161
161
  end
162
162
 
163
+ def element_payload
164
+ element.payload if element.is_a? Pacer::Payload::Element
165
+ end
166
+
163
167
  protected
164
168
 
165
169
  def after_initialize
@@ -40,7 +40,7 @@ module Pacer::Wrappers
40
40
  if element.is_a? ElementWrapper
41
41
  element = element.element
42
42
  end
43
- index.put key, value, element
43
+ index.put key.to_s, value, element
44
44
  end
45
45
  end
46
46
  end
@@ -0,0 +1,85 @@
1
+ module Pacer
2
+ module Wrappers
3
+ class PathWrappingPipeFunction
4
+ include com.tinkerpop.pipes.PipeFunction
5
+
6
+ attr_reader :block, :graph, :wrapper
7
+
8
+ def initialize(back, block)
9
+ @block = block
10
+ if back
11
+ @graph = back.graph
12
+ end
13
+ @wrapper = WrapperSelector.build
14
+ end
15
+
16
+ def arity
17
+ block.arity
18
+ end
19
+
20
+ def compute(path)
21
+ if path.first.is_a? Pacer::Wrappers::ElementWrapper
22
+ block.call path
23
+ else
24
+ p = path.map do |element|
25
+ wrapper.new graph, element
26
+ end
27
+ block.call p
28
+ end
29
+ end
30
+
31
+ alias call compute
32
+
33
+ def call_with_args(element, *args)
34
+ if path.first.is_a? Pacer::Wrappers::ElementWrapper
35
+ block.call path, *args
36
+ else
37
+ p = path.map do |element|
38
+ wrapper.new graph, element
39
+ end
40
+ block.call p, *args
41
+ end
42
+ end
43
+ end
44
+
45
+ class PathUnwrappingPipeFunction
46
+ include com.tinkerpop.pipes.PipeFunction
47
+
48
+ attr_reader :block
49
+
50
+ def initialize(block)
51
+ @block = block
52
+ end
53
+
54
+ def arity
55
+ block.arity
56
+ end
57
+
58
+ def compute(path)
59
+ unwrap block.call path
60
+ end
61
+
62
+ alias call compute
63
+
64
+ def call_with_args(path, *args)
65
+ unwrap block.call path, *args
66
+ end
67
+
68
+ def unwrap(p)
69
+ if p.is_a? Array
70
+ p.map do |e|
71
+ if e.is_a? ElementWrapper
72
+ e.element
73
+ else
74
+ e
75
+ end
76
+ end
77
+ elsif p.is_a? ElementWrapper
78
+ p.element
79
+ else
80
+ p
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -4,9 +4,12 @@ module Pacer::Wrappers
4
4
  include Pacer::Core::Graph::VerticesRoute
5
5
 
6
6
  def_delegators :@element,
7
- :getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty,
8
- :getEdges,
9
- :getRawVertex
7
+ # Object
8
+ :equals, :toString, :hashCode,
9
+ # Element
10
+ :getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty, :getRawElement,
11
+ # Vertex
12
+ :getEdges, :getVertices, :query, :getRawVertex
10
13
 
11
14
  class << self
12
15
  def wrappers
@@ -164,6 +167,18 @@ module Pacer::Wrappers
164
167
  get_edges_helper Pacer::Pipes::BOTH, *labels_and_extensions
165
168
  end
166
169
 
170
+ def out_vertices(*labels_and_extensions)
171
+ get_vertices_helper Pacer::Pipes::OUT, *labels_and_extensions
172
+ end
173
+
174
+ def in_vertices(*labels_and_extensions)
175
+ get_vertices_helper Pacer::Pipes::IN, *labels_and_extensions
176
+ end
177
+
178
+ def both_vertices(*labels_and_extensions)
179
+ get_vertices_helper Pacer::Pipes::BOTH, *labels_and_extensions
180
+ end
181
+
167
182
  # Test equality to another object.
168
183
  #
169
184
  # Elements are equal if they are the same type and have the same id
@@ -190,6 +205,14 @@ module Pacer::Wrappers
190
205
  element.hash
191
206
  end
192
207
 
208
+ def element_payload=(data)
209
+ if element.is_a? Pacer::Payload::Vertex
210
+ element.payload = data
211
+ else
212
+ @element = Pacer::Payload::Vertex.new element, data
213
+ end
214
+ end
215
+
193
216
  protected
194
217
 
195
218
  def get_edges_helper(direction, *labels_and_extensions)
@@ -199,6 +222,13 @@ module Pacer::Wrappers
199
222
  pipe
200
223
  end
201
224
 
225
+ def get_vertices_helper(direction, *labels_and_extensions)
226
+ labels, exts = split_labels_and_extensions(labels_and_extensions)
227
+ pipe = Pacer::Pipes::WrappingPipe.new graph, :vertex, exts
228
+ pipe.setStarts element.getVertices(direction, *labels).iterator
229
+ pipe
230
+ end
231
+
202
232
  def split_labels_and_extensions(mixed)
203
233
  labels = Set[]
204
234
  exts = []
data/pom.xml CHANGED
@@ -7,7 +7,7 @@
7
7
  <artifactId>pacer</artifactId>
8
8
  <!-- NOTE: the following properties are automatically updated based on the values in lib/pacer-neo4j/version.rb -->
9
9
  <properties>
10
- <gem.version>1.0.3</gem.version>
10
+ <gem.version>1.1.0</gem.version>
11
11
  <blueprints.version>2.1.0</blueprints.version>
12
12
  <pipes.version>2.1.0</pipes.version>
13
13
  <gremlin.version>2.1.0</gremlin.version>
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ # edge filters are also tested in filters_spec
4
+ module Pacer::Filter::PropertyFilter
5
+ Run.tg do
6
+ describe EdgeFilters do
7
+ subject { filters }
8
+
9
+ context 'symbol label' do
10
+ let(:filters) { Pacer::Route.edge_filters [:label] }
11
+
12
+ its(:any?) { should be_true }
13
+ its(:labels) { should == ['label'] }
14
+ its(:extensions_only?) { should be_false }
15
+ its(:extensions) { should be_empty }
16
+ its(:route_modules) { should be_empty }
17
+ its(:wrapper) { should be_nil }
18
+ its(:blocks) { should be_empty }
19
+ its(:properties) { should be_empty }
20
+ end
21
+
22
+ context 'symbol labels' do
23
+ let(:filters) { Pacer::Route.edge_filters [:label, :label2] }
24
+
25
+ its(:any?) { should be_true }
26
+ its(:labels) { should == ['label', 'label2'] }
27
+ end
28
+
29
+ context 'labels arrays' do
30
+ let(:filters) { Pacer::Route.edge_filters ["label", [:label2]] }
31
+
32
+ its(:any?) { should be_true }
33
+ its(:labels) { should == ['label', 'label2'] }
34
+ end
35
+
36
+ context 'labels and properties' do
37
+ let(:filters) { Pacer::Route.edge_filters [:label, { prop: 'value' }] }
38
+
39
+ its(:any?) { should be_true }
40
+ its(:labels) { should == ['label'] }
41
+ its(:properties) { should == [['prop', 'value']] }
42
+ end
43
+
44
+ context 'labels and extension' do
45
+ let(:filters) { Pacer::Route.edge_filters [:label, TP::Person] }
46
+
47
+ its(:any?) { should be_true }
48
+ its(:labels) { should == ['label'] }
49
+ its(:extensions) { should == [TP::Person] }
50
+ its(:properties) { should == [ %w[ type person ] ] }
51
+ end
52
+
53
+ context 'labels and simple extension' do
54
+ let(:filters) { Pacer::Route.edge_filters [:label, Tackle::SimpleMixin] }
55
+
56
+ its(:any?) { should be_true }
57
+ its(:labels) { should == ['label'] }
58
+ its(:extensions) { should == [Tackle::SimpleMixin] }
59
+ its(:properties) { should be_empty }
60
+ end
61
+ end
62
+ end
63
+ end
@@ -3,17 +3,17 @@ require 'spec_helper'
3
3
  module Pacer::Filter::PropertyFilter
4
4
 
5
5
  Run.tg do
6
- describe Filters do
6
+ shared_examples Filters do
7
7
  subject { filters }
8
8
 
9
9
  context 'no properties' do
10
- let(:filters) { Pacer::Route.filters [] }
10
+ let(:filters) { Pacer::Route.send filter_method, [] }
11
11
 
12
12
  its(:any?) { should be_false }
13
13
  end
14
14
 
15
15
  context 'no properties' do
16
- let(:filters) { Pacer::Route.filters [Tackle::SimpleMixin] }
16
+ let(:filters) { Pacer::Route.send filter_method, [Tackle::SimpleMixin] }
17
17
 
18
18
  its(:any?) { should be_true }
19
19
  its(:extensions_only?) { should be_true }
@@ -25,7 +25,7 @@ module Pacer::Filter::PropertyFilter
25
25
  end
26
26
 
27
27
  context 'simple properties' do
28
- let(:filters) { Pacer::Route.filters([name: 'Darrick', nickname: 'pangloss']) }
28
+ let(:filters) { Pacer::Route.send filter_method, [name: 'Darrick', nickname: 'pangloss'] }
29
29
 
30
30
  its(:any?) { should be_true }
31
31
  its(:extensions_only?) { should be_false }
@@ -37,7 +37,7 @@ module Pacer::Filter::PropertyFilter
37
37
  end
38
38
 
39
39
  context 'with extensions' do
40
- let(:filters) { Pacer::Route.filters([TP::Person, name: 'Darrick', nickname: 'pangloss']) }
40
+ let(:filters) { Pacer::Route.send filter_method, [TP::Person, name: 'Darrick', nickname: 'pangloss'] }
41
41
 
42
42
  its(:any?) { should be_true }
43
43
  its(:extensions) { should == [TP::Person] }
@@ -113,7 +113,7 @@ module Pacer::Filter::PropertyFilter
113
113
 
114
114
  context 'with route module' do
115
115
  # TODO: should this feature be removed?
116
- let(:filters) { Pacer::Route.filters [TP::Pangloss] }
116
+ let(:filters) { Pacer::Route.send filter_method, [TP::Pangloss] }
117
117
 
118
118
  its(:any?) { should be_true }
119
119
  its(:extensions_only?) { should be_false }
@@ -125,7 +125,7 @@ module Pacer::Filter::PropertyFilter
125
125
  end
126
126
 
127
127
  context 'with manual index' do
128
- let(:filters) { Pacer::Route.filters [tokens: { short: '555555' }, name: 'Darrick'] }
128
+ let(:filters) { Pacer::Route.send filter_method, [tokens: { short: '555555' }, name: 'Darrick'] }
129
129
 
130
130
  its(:any?) { should be_true }
131
131
  its(:extensions) { should be_empty }
@@ -165,5 +165,15 @@ module Pacer::Filter::PropertyFilter
165
165
  end
166
166
  end
167
167
  end
168
+
169
+ describe 'vertex' do
170
+ let(:filter_method) { :filters }
171
+ it_uses Filters
172
+ end
173
+
174
+ describe 'edge' do
175
+ let(:filter_method) { :edge_filters }
176
+ it_uses Filters
177
+ end
168
178
  end
169
179
  end