pacer 1.0.2-java → 1.0.3-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.
- data/blog/2012-09-18-pacer-1.0.md +63 -0
- data/lib/pacer/core/graph/element_route.rb +8 -4
- data/lib/pacer/core/graph/vertices_route.rb +1 -1
- data/lib/pacer/core/route.rb +20 -0
- data/lib/pacer/exceptions.rb +1 -0
- data/lib/pacer/filter/future_filter.rb +2 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +13 -12
- data/lib/pacer/graph/hash_index.rb +29 -0
- data/lib/pacer/graph/pacer_graph.rb +23 -6
- data/lib/pacer/graph/simple_encoder.rb +9 -4
- data/lib/pacer/graph/yaml_encoder.rb +18 -31
- data/lib/pacer/loader.rb +93 -0
- data/lib/pacer/route/mixin/bulk_operations.rb +1 -1
- data/lib/pacer/route.rb +0 -151
- data/lib/pacer/route_builder.rb +142 -0
- data/lib/pacer/side_effect/as.rb +1 -3
- data/lib/pacer/version.rb +1 -1
- data/lib/pacer/wrappers/edge_wrapper.rb +13 -16
- data/lib/pacer/wrappers/element_wrapper.rb +12 -22
- data/lib/pacer/wrappers/vertex_wrapper.rb +7 -4
- data/lib/{pacer-1.0.2-standalone.jar → pacer-1.0.3-standalone.jar} +0 -0
- data/lib/pacer.rb +9 -15
- data/pom.xml +1 -1
- data/spec/pacer/blueprints/dex_spec.rb +1 -154
- data/spec/pacer/blueprints/neo4j_spec.rb +8 -154
- data/spec/pacer/blueprints/orient_spec.rb +5 -0
- data/spec/pacer/blueprints/tg_spec.rb +1 -76
- data/spec/pacer/core/graph/vertices_route_spec.rb +32 -5
- data/spec/pacer/graph/pacer_graph_spec.rb +304 -336
- data/spec/pacer/graph/simple_encoder_spec.rb +78 -0
- data/spec/pacer/graph/yaml_encoder_spec.rb +71 -0
- data/spec/pacer/transform/join_spec.rb +1 -1
- data/spec/pacer/utils/tsort_spec.rb +1 -3
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +46 -40
- data/spec/pacer/wrapper/element_wrapper_spec.rb +8 -13
- data/spec/support/graph_runner.rb +12 -3
- metadata +13 -14
- data/lib/pacer/blueprints.rb +0 -3
- data/lib/pacer/core.rb +0 -8
- data/lib/pacer/filter.rb +0 -17
- data/lib/pacer/graph.rb +0 -12
- data/lib/pacer/route/mixins.rb +0 -2
- data/lib/pacer/routes.rb +0 -6
- data/lib/pacer/side_effect.rb +0 -11
- data/lib/pacer/support.rb +0 -10
- data/lib/pacer/transform.rb +0 -16
- data/lib/pacer/visitors.rb +0 -7
- data/lib/pacer/wrappers.rb +0 -21
@@ -0,0 +1,63 @@
|
|
1
|
+
What's new in Pacer 1.0
|
2
|
+
===
|
3
|
+
|
4
|
+
We're very excited about the latest version of Pacer. We've used Pacer
|
5
|
+
0.9 for almost a year now and it's served us very well, but in that time
|
6
|
+
we found a few pieces that we weren't happy with. We've addressed those
|
7
|
+
issues and also made improvements in its architecture, consistency, and
|
8
|
+
performance. So, here's what's new in Pacer 1.0:
|
9
|
+
|
10
|
+
* The already comprehensive spec suite has been improved and also
|
11
|
+
runs almost 10x faster.
|
12
|
+
|
13
|
+
* Graphs and elements are always wrapped. Previously, Pacer
|
14
|
+
patched the raw Java classes to add the methods it needs in addition
|
15
|
+
to allowing elements to be wrapped. By choosing to always use
|
16
|
+
wrapping, we can provide a cleaner, easier, and more consistent
|
17
|
+
interface.
|
18
|
+
* It uses the current [Tinkerpop](http://tinkerpop.com/) 2.1 stack with the most current versions
|
19
|
+
of all of its supported databases including [Neo4j](http://neo4j.org),
|
20
|
+
[Dex](http://www.sparsity-technologies.com/dex.php),
|
21
|
+
[OrientDB](http://www.orientdb.org/index.htm), and
|
22
|
+
[TinkerGraph](https://github.com/tinkerpop/blueprints/wiki/TinkerGraph). This is great news because
|
23
|
+
the Tinkerpop stack and the graphs that it supports are constantly
|
24
|
+
improving.
|
25
|
+
* The pacer-[graphdb] gems are no longer required but are all updated as a
|
26
|
+
convenient way to get the dependent jars without the pain of using maven.
|
27
|
+
* Pacer can fully support all of [Blueprints](https://github.com/tinkerpop/blueprints/wiki)'
|
28
|
+
WrapperGraph implementations. If you need the functionality behind one of the wrappers or want to
|
29
|
+
create your own, simply initialize a new PacerGraph with the wrapped
|
30
|
+
graph.
|
31
|
+
* Pacer is now able to fully support all [Gremlin](https://github.com/tinkerpop/gremlin/wiki) pipes including those
|
32
|
+
that require PipeFunctions, making all features in Gremlin available
|
33
|
+
to Pacer in addition to Pacer's own unique features.
|
34
|
+
* Many internal details of the implementation have been improved to make
|
35
|
+
Pacer's source much easier to understand and extend. This provides a
|
36
|
+
solid base on which to develop sophisticated projects.
|
37
|
+
|
38
|
+
|
39
|
+
Breaking changes and upgrade notes
|
40
|
+
---
|
41
|
+
|
42
|
+
Breaking changes have been kept to a minimum but there were a number of
|
43
|
+
places that we weren't happy with the previous implementation and have
|
44
|
+
addressed them.
|
45
|
+
|
46
|
+
* Pacer now requires [JRuby](http://jruby.org/) 1.7. This latest version of JRuby handles Java
|
47
|
+
exceptions significantly more cleanly which eliminated a problem we
|
48
|
+
previously had to work around in numerous places. In addition it is
|
49
|
+
now in 1.9 mode by default, starts up faster, and conforms to the more
|
50
|
+
recent Ruby 1.9.3 which brings valuable improvements to the standard
|
51
|
+
Ruby libraries.
|
52
|
+
|
53
|
+
* To find an index, the `#index_name` method has been renamed to `#index`.
|
54
|
+
* All `#element_type` methods now return simply `:vertex`, `:edge`, `:mixed`
|
55
|
+
or `:object`.
|
56
|
+
* The `#extensions` method sometimes returned a Set and sometimes an Array. Now it
|
57
|
+
always returns an Array.
|
58
|
+
* Elements yielded to a block within a route no longer have the
|
59
|
+
BlockFilterElement extension added to them. In the rare occasion that
|
60
|
+
you need to use the `#back` or `#vars` methods within a block, they
|
61
|
+
can be easily accessed by referring to the route itself within the
|
62
|
+
block. To see an example, refer to the `as_spec.rb` file.
|
63
|
+
|
@@ -75,9 +75,13 @@ module Pacer::Core::Graph
|
|
75
75
|
def [](prop_or_subset)
|
76
76
|
case prop_or_subset
|
77
77
|
when String, Symbol
|
78
|
-
chain_route(:element_type => :object,
|
78
|
+
route = chain_route(:element_type => :object,
|
79
79
|
:pipe_class => Pacer::Pipes::PropertyPipe,
|
80
|
-
:pipe_args => [prop_or_subset.to_s]
|
80
|
+
:pipe_args => [prop_or_subset.to_s],
|
81
|
+
:lookahead_replacement => proc { |r| r.back.property?(prop_or_subset) })
|
82
|
+
route.map(route_name: 'decode', remove_from_lookahead: true) do |v|
|
83
|
+
graph.decode_property(v)
|
84
|
+
end
|
81
85
|
when Fixnum
|
82
86
|
range(prop_or_subset, prop_or_subset)
|
83
87
|
when Range
|
@@ -85,7 +89,7 @@ module Pacer::Core::Graph
|
|
85
89
|
when Array
|
86
90
|
if prop_or_subset.all? { |i| i.is_a? String or i.is_a? Symbol }
|
87
91
|
map do |element|
|
88
|
-
prop_or_subset
|
92
|
+
element[prop_or_subset]
|
89
93
|
end
|
90
94
|
end
|
91
95
|
end
|
@@ -98,7 +102,7 @@ module Pacer::Core::Graph
|
|
98
102
|
def property?(name)
|
99
103
|
chain_route(:element_type => :object,
|
100
104
|
:pipe_class => Pacer::Pipes::PropertyPipe,
|
101
|
-
:pipe_args => [name.to_s,
|
105
|
+
:pipe_args => [name.to_s, false])
|
102
106
|
end
|
103
107
|
|
104
108
|
# Attach a route to the element id for each element emitted by the
|
@@ -174,7 +174,7 @@ module Pacer::Core::Graph
|
|
174
174
|
has_props = !props.empty?
|
175
175
|
edge_ids = []
|
176
176
|
counter = 0
|
177
|
-
graph.transaction do |commit, rollback|
|
177
|
+
graph.transaction(nesting: true) do |commit, rollback|
|
178
178
|
v.each do |from_v|
|
179
179
|
to_vertices.each do |to_v|
|
180
180
|
counter += 1
|
data/lib/pacer/core/route.rb
CHANGED
@@ -31,6 +31,22 @@ module Pacer
|
|
31
31
|
# @todo move this to graph routes.
|
32
32
|
attr_writer :graph
|
33
33
|
|
34
|
+
# If this piece of the route is useless in a lookahead, set this to true
|
35
|
+
# and when it is at the tail of a lookahead, it will be removed
|
36
|
+
# automatically. (for instance the property decoder, or wrap/unwrap)
|
37
|
+
attr_accessor :remove_from_lookahead
|
38
|
+
|
39
|
+
# If a route's function won't do the expected thing in a lookahead, set a
|
40
|
+
# proc here that will correct the route. For instance:
|
41
|
+
#
|
42
|
+
# g.v.lookahead { |v| v[:prop] }
|
43
|
+
#
|
44
|
+
# gets transformed to:
|
45
|
+
#
|
46
|
+
# g.v.lookahead { |v| v.property?(:prop) }
|
47
|
+
#
|
48
|
+
attr_accessor :lookahead_replacement
|
49
|
+
|
34
50
|
# Return which graph this route operates on.
|
35
51
|
#
|
36
52
|
# @todo move this to graph routes.
|
@@ -46,6 +62,10 @@ module Pacer
|
|
46
62
|
graph.equals g
|
47
63
|
end
|
48
64
|
|
65
|
+
def chain_route(args_hash)
|
66
|
+
Pacer::RouteBuilder.current.chain self, args_hash
|
67
|
+
end
|
68
|
+
|
49
69
|
# The arguments passed to the pipe constructor.
|
50
70
|
#
|
51
71
|
# @overload pipe_args
|
data/lib/pacer/exceptions.rb
CHANGED
@@ -7,6 +7,7 @@ module Pacer
|
|
7
7
|
class LogicError < Error; end
|
8
8
|
class ClientError < LogicError; end
|
9
9
|
class TransactionConcludedError < ClientError; end
|
10
|
+
class NestedTransactionError < ClientError; end
|
10
11
|
class NestedTransactionRollback < ClientError; end
|
11
12
|
class NestedMockTransactionRollback < NestedTransactionRollback; end
|
12
13
|
class MockTransactionRollback < ClientError; end
|
@@ -44,6 +44,8 @@ module Pacer
|
|
44
44
|
block, negate = @future_filter
|
45
45
|
@future_filter = nil
|
46
46
|
route = block.call(Pacer::Route.empty(self))
|
47
|
+
route = route.back while route.remove_from_lookahead
|
48
|
+
route = route.lookahead_replacement.call(route) if route.lookahead_replacement
|
47
49
|
if min or max
|
48
50
|
route = route.has_count_route(:min => min, :max => max).is(true)
|
49
51
|
end
|
@@ -1,14 +1,9 @@
|
|
1
1
|
module Pacer
|
2
2
|
import com.tinkerpop.blueprints.TransactionalGraph
|
3
3
|
|
4
|
-
# Add features to transactions to allow them to be more rubyish and
|
5
|
-
# more convenient to use.
|
6
|
-
#
|
7
|
-
# TODO: the method names in this module need to be cleaned up.
|
8
|
-
# TODO: some methods may be able to be eliminated.
|
9
4
|
module GraphTransactionsMixin
|
10
5
|
def in_transaction?
|
11
|
-
threadlocal_graph_info
|
6
|
+
threadlocal_graph_info.fetch(:tx_depth, 0) > 0
|
12
7
|
end
|
13
8
|
|
14
9
|
# Basic usage:
|
@@ -34,8 +29,12 @@ module Pacer
|
|
34
29
|
# Also considering a 3rd callback that could be used to get info about the
|
35
30
|
# current transaction stack like depth, number of commits/rollbacks, possibly the number of
|
36
31
|
# mutations it wraps and even some event registration stuff could be made available.
|
37
|
-
|
38
|
-
|
32
|
+
#
|
33
|
+
# opts:
|
34
|
+
# nesting: true -- allow mock nested transactions
|
35
|
+
# nesting: false -- (default) raise an exception instead of starting a nested transaction
|
36
|
+
def transaction(opts = {})
|
37
|
+
commit, rollback = start_transaction! opts
|
39
38
|
begin
|
40
39
|
r = yield commit, rollback
|
41
40
|
commit.call
|
@@ -55,15 +54,17 @@ module Pacer
|
|
55
54
|
graphs[blueprints_graph.object_id] ||= {}
|
56
55
|
end
|
57
56
|
|
58
|
-
def start_transaction!
|
57
|
+
def start_transaction!(opts)
|
59
58
|
tgi = threadlocal_graph_info
|
60
59
|
tx_depth = tgi[:tx_depth] ||= 0
|
61
60
|
tgi[:tx_depth] += 1
|
62
61
|
if blueprints_graph.is_a? TransactionalGraph
|
63
62
|
if tx_depth == 0
|
64
63
|
base_tx_finalizers
|
65
|
-
|
64
|
+
elsif opts[:nesting] == true
|
66
65
|
nested_tx_finalizers
|
66
|
+
else
|
67
|
+
fail NestedTransactionError, "To use nested transactions, use nesting: true"
|
67
68
|
end
|
68
69
|
else
|
69
70
|
if tx_depth == 0
|
@@ -75,14 +76,14 @@ module Pacer
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def finish_transaction!
|
78
|
-
threadlocal_graph_info[:tx_depth] -= 1
|
79
|
+
threadlocal_graph_info[:tx_depth] -= 1 rescue nil
|
79
80
|
end
|
80
81
|
|
81
82
|
def base_tx_finalizers
|
82
83
|
tx_id = threadlocal_graph_info[:tx_id] = rand
|
83
84
|
commit = -> do
|
84
85
|
if tx_id != threadlocal_graph_info[:tx_id]
|
85
|
-
fail InternalError
|
86
|
+
fail InternalError, 'Can not commit transaction outside its original block'
|
86
87
|
end
|
87
88
|
puts "transaction committed" if Pacer.verbose == :very
|
88
89
|
blueprints_graph.stopTransaction TransactionalGraph::Conclusion::SUCCESS
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pacer::Graph
|
2
|
+
class HashIndex
|
3
|
+
attr_reader :name, :type
|
4
|
+
|
5
|
+
def initialize(element_type, name)
|
6
|
+
@type = type
|
7
|
+
@name = name
|
8
|
+
@data = Hash.new do |h, k|
|
9
|
+
h[k] = Hash.new { |h, k| h[k] = Set[] }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(key, value)
|
14
|
+
Pacer::Pipes::EnumerablePipe.new data[key][value]
|
15
|
+
end
|
16
|
+
|
17
|
+
def put(key, value, element)
|
18
|
+
data[key][value] << element
|
19
|
+
end
|
20
|
+
|
21
|
+
def count(key, value)
|
22
|
+
data[key][value].count
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :data
|
28
|
+
end
|
29
|
+
end
|
@@ -188,10 +188,6 @@ module Pacer
|
|
188
188
|
end
|
189
189
|
|
190
190
|
module Encoding
|
191
|
-
def sanitize_properties(props)
|
192
|
-
encoder.sanitize_properties props
|
193
|
-
end
|
194
|
-
|
195
191
|
def encode_property(value)
|
196
192
|
encoder.encode_property value
|
197
193
|
end
|
@@ -270,7 +266,7 @@ module Pacer
|
|
270
266
|
# @option opts [true] :create create the index if it doesn't exist
|
271
267
|
# @return [Pacer::IndexMixin]
|
272
268
|
def index(name, type = nil, opts = {})
|
273
|
-
return unless features.supportsIndices
|
269
|
+
return temp_index(name, type, opts) unless features.supportsIndices
|
274
270
|
name = name.to_s
|
275
271
|
if type
|
276
272
|
type = index_class element_type type
|
@@ -285,7 +281,7 @@ module Pacer
|
|
285
281
|
end
|
286
282
|
|
287
283
|
def drop_index(idx)
|
288
|
-
return unless features.supportsIndices
|
284
|
+
return drop_temp_index(idx) unless features.supportsIndices
|
289
285
|
if idx.is_a? String or idx.is_a? Symbol
|
290
286
|
blueprints_graph.dropIndex idx
|
291
287
|
else
|
@@ -293,6 +289,27 @@ module Pacer
|
|
293
289
|
end
|
294
290
|
end
|
295
291
|
|
292
|
+
def temp_index(name, type = nil, opts = {})
|
293
|
+
@temp_indices ||= {}
|
294
|
+
idx = @temp_indices[name]
|
295
|
+
unless idx
|
296
|
+
if name and type and opts[:create]
|
297
|
+
idx = @temp_indices[name] = Pacer::Graph::HashIndex.new type, name
|
298
|
+
elsif opts[:create]
|
299
|
+
idx = Pacer::Graph::HashIndex.new type, nil
|
300
|
+
end
|
301
|
+
end
|
302
|
+
Pacer::Wrappers::IndexWrapper.new self, idx, idx.type if idx
|
303
|
+
end
|
304
|
+
|
305
|
+
def drop_temp_index(idx)
|
306
|
+
@temp_indices.delete idx.name
|
307
|
+
end
|
308
|
+
|
309
|
+
def drop_temp_indices
|
310
|
+
@temp_indices = {}
|
311
|
+
end
|
312
|
+
|
296
313
|
# Return an object that can be compared to the return value of
|
297
314
|
# Index#index_class.
|
298
315
|
def index_class(et)
|
@@ -1,20 +1,25 @@
|
|
1
1
|
module Pacer
|
2
2
|
class SimpleEncoder
|
3
|
-
|
4
|
-
|
5
|
-
end
|
3
|
+
JBoolean = java.lang.Boolean
|
4
|
+
JFalse = false.to_java
|
6
5
|
|
7
6
|
def self.encode_property(value)
|
8
7
|
if value.is_a? String
|
9
8
|
value = value.strip
|
10
9
|
value unless value == ''
|
10
|
+
elsif false == value
|
11
|
+
JFalse
|
11
12
|
else
|
12
13
|
value
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
17
|
def self.decode_property(value)
|
17
|
-
value
|
18
|
+
if value.is_a? JBoolean and value == JFalse
|
19
|
+
false
|
20
|
+
else
|
21
|
+
value
|
22
|
+
end
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
@@ -5,13 +5,6 @@ module Pacer
|
|
5
5
|
# Neo4j could and for everything else it uses (slow (but easy))
|
6
6
|
# human-readable YAML encoding.
|
7
7
|
class YamlEncoder
|
8
|
-
def self.sanitize_properties(props)
|
9
|
-
pairs = props.map do |name, value|
|
10
|
-
[name, encode_property(value)]
|
11
|
-
end
|
12
|
-
Hash[pairs]
|
13
|
-
end
|
14
|
-
|
15
8
|
def self.encode_property(value)
|
16
9
|
case value
|
17
10
|
when nil
|
@@ -22,12 +15,12 @@ module Pacer
|
|
22
15
|
value
|
23
16
|
when Numeric
|
24
17
|
if value.is_a? Bignum
|
25
|
-
value
|
18
|
+
dump value
|
26
19
|
else
|
27
|
-
value
|
20
|
+
value.to_java
|
28
21
|
end
|
29
22
|
when true, false
|
30
|
-
value
|
23
|
+
value.to_java
|
31
24
|
when Array
|
32
25
|
if value.length == 0
|
33
26
|
value_type = Fixnum
|
@@ -51,33 +44,27 @@ module Pacer
|
|
51
44
|
when String
|
52
45
|
value.to_java :string
|
53
46
|
else
|
54
|
-
value
|
47
|
+
dump value
|
55
48
|
end
|
56
49
|
else
|
57
|
-
value
|
50
|
+
dump value
|
58
51
|
end
|
59
52
|
end
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
value
|
69
|
-
end
|
70
|
-
end
|
71
|
-
else
|
72
|
-
def self.decode_property(value)
|
73
|
-
if value.is_a? String and value[0, 3] == '---'
|
74
|
-
YAML.load(value)
|
75
|
-
elsif value.is_a? ArrayJavaProxy
|
76
|
-
value.to_a
|
77
|
-
else
|
78
|
-
value
|
79
|
-
end
|
54
|
+
def self.decode_property(value)
|
55
|
+
if value.is_a? String and value[0, 1] == ' '
|
56
|
+
YAML.load(value[1..-1])
|
57
|
+
elsif value.is_a? ArrayJavaProxy
|
58
|
+
value.to_a
|
59
|
+
else
|
60
|
+
value
|
80
61
|
end
|
81
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def self.dump(value)
|
67
|
+
" #{ YAML.dump value }"
|
68
|
+
end
|
82
69
|
end
|
83
70
|
end
|
data/lib/pacer/loader.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
module Pacer
|
2
|
+
import com.tinkerpop.blueprints.Graph
|
3
|
+
import com.tinkerpop.blueprints.Element
|
4
|
+
import com.tinkerpop.blueprints.Vertex
|
5
|
+
import com.tinkerpop.blueprints.Edge
|
6
|
+
|
7
|
+
module Core end
|
8
|
+
module Routes end
|
9
|
+
module Wrappers end
|
10
|
+
module Support end
|
11
|
+
module Visitors end
|
12
|
+
module Filter end
|
13
|
+
module Transform end
|
14
|
+
module SideEffect end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
require 'pacer/exceptions'
|
19
|
+
require 'pacer/pipes'
|
20
|
+
|
21
|
+
require 'pacer/core/route'
|
22
|
+
require 'pacer/core/graph'
|
23
|
+
require 'pacer/core/side_effect'
|
24
|
+
|
25
|
+
require 'pacer/graph/graph_transactions_mixin'
|
26
|
+
require 'pacer/graph/pacer_graph'
|
27
|
+
require 'pacer/graph/simple_encoder'
|
28
|
+
require 'pacer/graph/yaml_encoder'
|
29
|
+
require 'pacer/graph/graph_ml'
|
30
|
+
require 'pacer/graph/hash_index'
|
31
|
+
|
32
|
+
require 'pacer/route/mixin/bulk_operations'
|
33
|
+
require 'pacer/route/mixin/route_operations'
|
34
|
+
|
35
|
+
require 'forwardable'
|
36
|
+
require 'pacer/wrappers/element_wrapper'
|
37
|
+
require 'pacer/wrappers/vertex_wrapper'
|
38
|
+
require 'pacer/wrappers/edge_wrapper'
|
39
|
+
require 'pacer/wrappers/index_wrapper'
|
40
|
+
require 'pacer/wrappers/wrapper_selector'
|
41
|
+
require 'pacer/wrappers/wrapping_pipe_function'
|
42
|
+
|
43
|
+
require 'pacer/route_builder'
|
44
|
+
require 'pacer/function_resolver'
|
45
|
+
require 'pacer/route'
|
46
|
+
|
47
|
+
require 'pacer/blueprints/tg'
|
48
|
+
require 'pacer/blueprints/ruby_graph'
|
49
|
+
require 'pacer/blueprints/multi_graph'
|
50
|
+
|
51
|
+
require 'pacer/support/array_list'
|
52
|
+
require 'pacer/support/enumerable'
|
53
|
+
require 'pacer/support/proc'
|
54
|
+
require 'pacer/support/hash'
|
55
|
+
require 'pacer/support/native_exception'
|
56
|
+
require 'pacer/support/nil_class'
|
57
|
+
|
58
|
+
require 'pacer/utils'
|
59
|
+
|
60
|
+
require 'pacer/visitors/visits_section'
|
61
|
+
require 'pacer/visitors/section'
|
62
|
+
|
63
|
+
require 'pacer/filter/collection_filter'
|
64
|
+
require 'pacer/filter/empty_filter'
|
65
|
+
require 'pacer/filter/future_filter'
|
66
|
+
require 'pacer/filter/property_filter'
|
67
|
+
require 'pacer/filter/range_filter'
|
68
|
+
require 'pacer/filter/uniq_filter'
|
69
|
+
require 'pacer/filter/index_filter'
|
70
|
+
require 'pacer/filter/loop_filter'
|
71
|
+
require 'pacer/filter/block_filter'
|
72
|
+
require 'pacer/filter/object_filter'
|
73
|
+
require 'pacer/filter/where_filter'
|
74
|
+
require 'pacer/filter/random_filter'
|
75
|
+
|
76
|
+
require 'pacer/transform/cap'
|
77
|
+
require 'pacer/transform/stream_sort'
|
78
|
+
require 'pacer/transform/stream_uniq'
|
79
|
+
require 'pacer/transform/gather'
|
80
|
+
require 'pacer/transform/map'
|
81
|
+
require 'pacer/transform/process'
|
82
|
+
require 'pacer/transform/join'
|
83
|
+
require 'pacer/transform/path'
|
84
|
+
require 'pacer/transform/scatter'
|
85
|
+
require 'pacer/transform/has_count_cap'
|
86
|
+
require 'pacer/transform/sort_section'
|
87
|
+
|
88
|
+
require 'pacer/side_effect/aggregate'
|
89
|
+
require 'pacer/side_effect/as'
|
90
|
+
require 'pacer/side_effect/group_count'
|
91
|
+
require 'pacer/side_effect/is_unique'
|
92
|
+
require 'pacer/side_effect/counted'
|
93
|
+
require 'pacer/side_effect/visitor'
|
@@ -24,7 +24,7 @@ module Pacer::Routes
|
|
24
24
|
target_graph.in_bulk_job = true
|
25
25
|
size ||= target_graph.bulk_job_size
|
26
26
|
counter = 0
|
27
|
-
target_graph.transaction do |commit, rollback|
|
27
|
+
target_graph.transaction(nesting: true) do |commit, rollback|
|
28
28
|
each_slice(size) do |slice|
|
29
29
|
print counter if Pacer.verbose?
|
30
30
|
counter += size
|
data/lib/pacer/route.rb
CHANGED
@@ -1,155 +1,4 @@
|
|
1
|
-
[Pacer::Core::Route, Pacer::Wrappers::ElementWrapper].each do |klass|
|
2
|
-
klass.class_eval %{
|
3
|
-
def chain_route(args_hash)
|
4
|
-
Pacer::RouteBuilder.current.chain self, args_hash
|
5
|
-
end
|
6
|
-
}
|
7
|
-
end
|
8
|
-
|
9
1
|
module Pacer
|
10
|
-
|
11
|
-
class RouteBuilder
|
12
|
-
class << self
|
13
|
-
attr_writer :current
|
14
|
-
|
15
|
-
def current
|
16
|
-
@current ||= RouteBuilder.new
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :types
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
@types = Hash.new do |h, type_def|
|
24
|
-
h[type_def] = Class.new(Route) do
|
25
|
-
type_def.each do |mods|
|
26
|
-
mods.each do |mod|
|
27
|
-
include mod
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def chain(source, args)
|
35
|
-
types[type_def(source, args)].new source, configuration(source, args), arguments(source, args)
|
36
|
-
end
|
37
|
-
|
38
|
-
protected
|
39
|
-
|
40
|
-
def source_value(source, name)
|
41
|
-
source.send name if source.respond_to? name
|
42
|
-
end
|
43
|
-
|
44
|
-
def type_def(source, args)
|
45
|
-
[
|
46
|
-
type_modules(source, args),
|
47
|
-
function_modules(source, args),
|
48
|
-
other_modules(source, args),
|
49
|
-
extension_modules(source, args)
|
50
|
-
]
|
51
|
-
end
|
52
|
-
|
53
|
-
def configuration(source, args)
|
54
|
-
{
|
55
|
-
element_type: element_type(source, args),
|
56
|
-
graph: graph(source, args),
|
57
|
-
extensions: extensions(source, args),
|
58
|
-
wrapper: wrapper(source, args),
|
59
|
-
function: function_modules(source, args).first
|
60
|
-
}
|
61
|
-
end
|
62
|
-
|
63
|
-
def arguments(source, args)
|
64
|
-
args.reject do |key, val|
|
65
|
-
Set[:element_type, :wrapper, :extensions, :modules, :graph, :back, :filter, :side_effect, :transform, :visitor].include? key
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def graph(source, args)
|
70
|
-
args[:graph] || source_value(source, :graph)
|
71
|
-
end
|
72
|
-
|
73
|
-
def element_type(source, args)
|
74
|
-
et = args[:element_type] || source_value(source, :element_type)
|
75
|
-
if not et
|
76
|
-
fail ClientError, "No element_type specified or inferred"
|
77
|
-
end
|
78
|
-
if not graph(source, args) and (et == :vertex or et == :edge or et == :mixed)
|
79
|
-
fail ClientError, "Element type #{ et.inspect } specified, but no graph specified."
|
80
|
-
end
|
81
|
-
et
|
82
|
-
end
|
83
|
-
|
84
|
-
def type_modules(source, args)
|
85
|
-
case element_type source, args
|
86
|
-
when :vertex
|
87
|
-
[Pacer::Core::Graph::ElementRoute, Pacer::Core::Graph::VerticesRoute]
|
88
|
-
when :edge
|
89
|
-
[Pacer::Core::Graph::ElementRoute, Pacer::Core::Graph::EdgesRoute]
|
90
|
-
when :mixed
|
91
|
-
[Pacer::Core::Graph::ElementRoute, Pacer::Core::Graph::MixedRoute]
|
92
|
-
else
|
93
|
-
[]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def other_modules(source, args)
|
98
|
-
[*args[:modules]]
|
99
|
-
end
|
100
|
-
|
101
|
-
def type_from_source?(source, args)
|
102
|
-
element_type(source, args) == source_value(source, :element_type)
|
103
|
-
end
|
104
|
-
|
105
|
-
def wrapper(source, args)
|
106
|
-
args.fetch(:wrapper) do
|
107
|
-
source_value(source, :wrapper) if type_from_source? source, args
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def extensions(source, args)
|
112
|
-
exts = args.fetch(:extensions) do
|
113
|
-
source_value(source, :extensions) if type_from_source? source, args
|
114
|
-
end
|
115
|
-
if exts.is_a? Set
|
116
|
-
exts.to_a
|
117
|
-
elsif exts.is_a? Module
|
118
|
-
[exts]
|
119
|
-
elsif exts.is_a? Array
|
120
|
-
exts.uniq
|
121
|
-
else
|
122
|
-
[]
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def all_extensions(source, args)
|
127
|
-
w = wrapper source, args
|
128
|
-
exts = extensions source, args
|
129
|
-
if w and exts
|
130
|
-
(w.extensions + exts).uniq
|
131
|
-
elsif w
|
132
|
-
w.extensions
|
133
|
-
elsif exts
|
134
|
-
exts
|
135
|
-
else
|
136
|
-
[]
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def extension_modules(source, args)
|
141
|
-
all_extensions(source, args).uniq.select do |mod|
|
142
|
-
mod.respond_to?(:const_defined?) and mod.const_defined? :Route
|
143
|
-
end.map { |mod| mod::Route }
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
def function_modules(source, args)
|
148
|
-
FunctionResolver.function(args).compact
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
|
153
2
|
# The base class for almost everything in Pacer. Every route is an
|
154
3
|
# instance of this class with a variety of modules mixed into the
|
155
4
|
# instance at runtime.
|