pacer 0.9.1.1-java → 1.0.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.
- data/.autotest +4 -1
- data/.gitignore +4 -0
- data/.rspec +1 -1
- data/Gemfile-dev +33 -0
- data/Gemfile-release +4 -0
- data/README.md +27 -9
- data/Rakefile +26 -8
- data/bin/autotest +1 -1
- data/lib/pacer/blueprints/multi_graph.rb +7 -19
- data/lib/pacer/blueprints/ruby_graph.rb +77 -52
- data/lib/pacer/blueprints/tg.rb +6 -93
- data/lib/pacer/blueprints.rb +0 -1
- data/lib/pacer/core/graph/edges_route.rb +10 -12
- data/lib/pacer/core/graph/element_route.rb +14 -21
- data/lib/pacer/core/graph/graph_index_route.rb +12 -8
- data/lib/pacer/core/graph/graph_route.rb +2 -5
- data/lib/pacer/core/graph/mixed_route.rb +3 -5
- data/lib/pacer/core/graph/vertices_route.rb +26 -27
- data/lib/pacer/core/route.rb +35 -66
- data/lib/pacer/exceptions.rb +13 -6
- data/lib/pacer/extensions/block_filter_element.rb +0 -5
- data/lib/pacer/filter/collection_filter.rb +9 -2
- data/lib/pacer/filter/empty_filter.rb +12 -3
- data/lib/pacer/filter/future_filter.rb +5 -5
- data/lib/pacer/filter/loop_filter.rb +7 -13
- data/lib/pacer/filter/object_filter.rb +10 -16
- data/lib/pacer/filter/property_filter/filters.rb +134 -93
- data/lib/pacer/filter/property_filter.rb +22 -19
- data/lib/pacer/filter/where_filter/node_visitor.rb +47 -26
- data/lib/pacer/filter/where_filter.rb +24 -3
- data/lib/pacer/function_resolver.rb +7 -2
- data/lib/pacer/graph/graph_ml.rb +39 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +107 -175
- data/lib/pacer/graph/pacer_graph.rb +438 -0
- data/lib/pacer/graph/simple_encoder.rb +20 -0
- data/lib/pacer/graph/yaml_encoder.rb +81 -0
- data/lib/pacer/graph.rb +8 -10
- data/lib/pacer/pipe/blackbox_pipeline.rb +11 -4
- data/lib/pacer/pipe/block_filter_pipe.rb +5 -22
- data/lib/pacer/pipe/cross_product_transform_pipe.rb +5 -7
- data/lib/pacer/pipe/edges_pipe.rb +22 -0
- data/lib/pacer/pipe/enumerable_pipe.rb +3 -9
- data/lib/pacer/pipe/expandable_pipe.rb +2 -14
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +2 -8
- data/lib/pacer/pipe/is_empty_pipe.rb +5 -12
- data/lib/pacer/pipe/is_unique_pipe.rb +3 -13
- data/lib/pacer/pipe/label_collection_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/label_prefix_pipe.rb +0 -6
- data/lib/pacer/pipe/loop_pipe.rb +27 -25
- data/lib/pacer/pipe/never_pipe.rb +1 -1
- data/lib/pacer/pipe/path_wrapping_pipe.rb +40 -0
- data/lib/pacer/pipe/process_pipe.rb +2 -20
- data/lib/pacer/pipe/property_comparison_pipe.rb +0 -6
- data/lib/pacer/pipe/ruby_pipe.rb +10 -3
- data/lib/pacer/pipe/simple_visitor_pipe.rb +12 -11
- data/lib/pacer/pipe/stream_sort_pipe.rb +1 -7
- data/lib/pacer/pipe/stream_uniq_pipe.rb +0 -6
- data/lib/pacer/pipe/type_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/unary_transform_pipe.rb +6 -8
- data/lib/pacer/pipe/unwrapping_pipe.rb +13 -0
- data/lib/pacer/pipe/vertices_pipe.rb +22 -0
- data/lib/pacer/pipe/visitor_pipe.rb +3 -7
- data/lib/pacer/pipe/wrapping_pipe.rb +37 -0
- data/lib/pacer/pipes.rb +17 -12
- data/lib/pacer/route/mixin/bulk_operations.rb +8 -9
- data/lib/pacer/route/mixin/route_operations.rb +17 -11
- data/lib/pacer/route/mixins.rb +0 -1
- data/lib/pacer/route.rb +198 -121
- data/lib/pacer/side_effect/aggregate.rb +22 -2
- data/lib/pacer/side_effect/as.rb +73 -0
- data/lib/pacer/side_effect/group_count.rb +0 -3
- data/lib/pacer/side_effect/is_unique.rb +7 -6
- data/lib/pacer/side_effect.rb +1 -1
- data/lib/pacer/support/enumerable.rb +14 -12
- data/lib/pacer/support/nil_class.rb +5 -0
- data/lib/pacer/support/proc.rb +2 -2
- data/lib/pacer/support.rb +1 -1
- data/lib/pacer/transform/cap.rb +1 -1
- data/lib/pacer/transform/has_count_cap.rb +1 -1
- data/lib/pacer/transform/join.rb +20 -16
- data/lib/pacer/transform/map.rb +6 -2
- data/lib/pacer/transform/path.rb +44 -20
- data/lib/pacer/transform/sort_section.rb +58 -51
- data/lib/pacer/utils/tsort.rb +7 -2
- data/lib/pacer/utils.rb +0 -1
- data/lib/pacer/version.rb +4 -3
- data/lib/pacer/visitors/section.rb +42 -0
- data/lib/pacer/visitors/visits_section.rb +32 -0
- data/lib/pacer/visitors.rb +7 -0
- data/lib/pacer/wrappers/edge_wrapper.rb +164 -11
- data/lib/pacer/wrappers/element_wrapper.rb +133 -8
- data/lib/pacer/wrappers/index_wrapper.rb +47 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +175 -12
- data/lib/pacer/wrappers/wrapper_selector.rb +40 -0
- data/lib/pacer/wrappers/wrapping_pipe_function.rb +90 -0
- data/lib/pacer/wrappers.rb +3 -1
- data/lib/pacer-1.0.0-standalone.jar +0 -0
- data/lib/pacer.rb +13 -47
- data/pacer.gemspec +0 -8
- data/pom.xml +10 -3
- data/spec/pacer/blueprints/dex_spec.rb +12 -26
- data/spec/pacer/blueprints/neo4j_spec.rb +14 -28
- data/spec/pacer/blueprints/tg_spec.rb +6 -54
- data/spec/pacer/core/graph/edges_route_spec.rb +1 -1
- data/spec/pacer/core/graph/element_route_spec.rb +2 -2
- data/spec/pacer/core/graph/graph_route_spec.rb +2 -2
- data/spec/pacer/core/graph/vertices_route_spec.rb +10 -3
- data/spec/pacer/core/route_spec.rb +35 -58
- data/spec/pacer/filter/empty_filter_spec.rb +5 -6
- data/spec/pacer/filter/future_filter_spec.rb +8 -8
- data/spec/pacer/filter/loop_filter_spec.rb +120 -6
- data/spec/pacer/filter/object_filter_spec.rb +15 -0
- data/spec/pacer/filter/property_filter/filters_spec.rb +169 -0
- data/spec/pacer/filter/property_filter_spec.rb +15 -12
- data/spec/pacer/filter/uniq_filter_spec.rb +1 -1
- data/spec/pacer/filter/where_filter_spec.rb +55 -7
- data/spec/pacer/graph/{graph_mixin_spec.rb → pacer_graph_spec.rb} +114 -185
- data/spec/pacer/route/mixin/base_spec.rb +36 -35
- data/spec/pacer/route/mixin/route_operations_spec.rb +4 -46
- data/spec/pacer/side_effect/as_spec.rb +34 -0
- data/spec/pacer/support/enumerable_spec.rb +6 -6
- data/spec/pacer/transform/join_spec.rb +7 -5
- data/spec/pacer/transform/map_spec.rb +55 -0
- data/spec/pacer/transform/path_spec.rb +30 -15
- data/spec/pacer/transform/process_spec.rb +42 -0
- data/spec/pacer/transform/sort_section_spec.rb +82 -0
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +122 -2
- data/spec/pacer/wrapper/element_wrapper_spec.rb +289 -3
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +289 -2
- data/spec/spec_helper.rb +16 -7
- data/spec/support/graph_runner.rb +80 -29
- data/tags +1165 -0
- metadata +46 -107
- data/.rvmrc +0 -0
- data/lib/pacer/blueprints/extensions.rb +0 -77
- data/lib/pacer/graph/edge_mixin.rb +0 -127
- data/lib/pacer/graph/element_mixin.rb +0 -202
- data/lib/pacer/graph/graph_indices_mixin.rb +0 -93
- data/lib/pacer/graph/graph_mixin.rb +0 -361
- data/lib/pacer/graph/index_mixin.rb +0 -30
- data/lib/pacer/graph/vertex_mixin.rb +0 -119
- data/lib/pacer/pipe/map_pipe.rb +0 -36
- data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +0 -26
- data/lib/pacer/route/mixin/variable_route_module.rb +0 -26
- data/lib/pacer/side_effect/section.rb +0 -25
- data/lib/pacer/support/iterator_mixins.rb +0 -110
- data/lib/pacer/wrappers/new_element.rb +0 -106
- data/lib/pacer-0.9.1.1-standalone.jar +0 -0
- data/spec/pacer/graph/edge_mixin_spec.rb +0 -116
- data/spec/pacer/graph/element_mixin_spec.rb +0 -297
- data/spec/pacer/graph/index_mixin_spec.rb +0 -0
- data/spec/pacer/graph/vertex_mixin_spec.rb +0 -192
@@ -2,19 +2,20 @@ module Pacer::Wrappers
|
|
2
2
|
class EdgeWrapper < ElementWrapper
|
3
3
|
include Pacer::Edge
|
4
4
|
include Pacer::Core::Graph::EdgesRoute
|
5
|
-
include Pacer::ElementMixin
|
6
|
-
include Pacer::EdgeMixin
|
7
5
|
|
8
6
|
def_delegators :@element,
|
9
7
|
:getId, :getLabel, :getPropertyKeys, :getProperty, :setProperty, :removeProperty,
|
10
|
-
:
|
11
|
-
:getRawEdge
|
12
|
-
:graph, :graph=, :<=>, :==
|
8
|
+
:getVertex,
|
9
|
+
:getRawEdge
|
13
10
|
|
14
11
|
class << self
|
15
12
|
def wrapper_for(exts)
|
16
13
|
@wrappers = {} unless defined? @wrappers
|
17
|
-
|
14
|
+
if exts
|
15
|
+
@wrappers[exts.to_set] ||= build_edge_wrapper(exts)
|
16
|
+
else
|
17
|
+
fail Pacer::LogicError, "Extensions should not be nil"
|
18
|
+
end
|
18
19
|
end
|
19
20
|
|
20
21
|
def clear_cache
|
@@ -30,22 +31,174 @@ module Pacer::Wrappers
|
|
30
31
|
|
31
32
|
# This method must be defined here rather than in the superclass in order
|
32
33
|
# to correctly override the method in an included module
|
33
|
-
|
34
|
-
|
34
|
+
attr_reader :element
|
35
|
+
|
36
|
+
def label
|
37
|
+
getLabel
|
38
|
+
end
|
39
|
+
|
40
|
+
# The incoming vertex for this edge.
|
41
|
+
# @return [Pacer::Wrappers::VertexWrapper]
|
42
|
+
def in_vertex(extensions = nil)
|
43
|
+
v = element.getVertex Pacer::Pipes::IN
|
44
|
+
if extensions.is_a? Enumerable
|
45
|
+
v = VertexWrapper.wrapper_for(extensions).new v
|
46
|
+
elsif extensions
|
47
|
+
v = VertexWrapper.wrapper_for([extensions]).new v
|
48
|
+
else
|
49
|
+
v = VertexWrapper.new v
|
50
|
+
end
|
51
|
+
v.graph = graph
|
52
|
+
v
|
53
|
+
end
|
54
|
+
|
55
|
+
# The outgoing vertex for this edge.
|
56
|
+
# @return [Pacer::Wrappers::VertexWrapper]
|
57
|
+
def out_vertex(extensions = nil)
|
58
|
+
v = element.getVertex Pacer::Pipes::OUT
|
59
|
+
if extensions.is_a? Enumerable
|
60
|
+
v = VertexWrapper.wrapper_for(extensions).new v
|
61
|
+
elsif extensions
|
62
|
+
v = VertexWrapper.wrapper_for([extensions]).new v
|
63
|
+
else
|
64
|
+
v = VertexWrapper.new v
|
65
|
+
end
|
66
|
+
v.graph = graph
|
67
|
+
v
|
35
68
|
end
|
36
69
|
|
37
70
|
# This method must be defined here rather than in the superclass in order
|
38
71
|
# to correctly override the method in an included module
|
39
|
-
def
|
40
|
-
|
72
|
+
def extensions
|
73
|
+
self.class.extensions
|
41
74
|
end
|
42
75
|
|
76
|
+
# Add extensions to this edge.
|
77
|
+
#
|
78
|
+
# If any extension has a Edge module within it, this edge will
|
79
|
+
# be extended with the extension's Edge module.
|
80
|
+
#
|
81
|
+
# @param [[extensions]] exts the extensions to add
|
82
|
+
# @return [Pacer::Wrappers::EdgeWrapper] this edge wrapped up and including
|
83
|
+
# the extensions
|
43
84
|
def add_extensions(exts)
|
44
85
|
if exts.any?
|
45
|
-
self.class.wrap(element, extensions + exts.to_a)
|
86
|
+
e = self.class.wrap(element, extensions + exts.to_a)
|
87
|
+
e.graph = graph
|
88
|
+
e
|
46
89
|
else
|
47
90
|
self
|
48
91
|
end
|
49
92
|
end
|
93
|
+
|
94
|
+
# Returns the element with a new simple wrapper.
|
95
|
+
# @return [EdgeWrapper]
|
96
|
+
def no_extensions
|
97
|
+
EdgeWrapper.new element
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns a human-readable representation of the edge using the
|
101
|
+
# standard ruby console representation of an instantiated object.
|
102
|
+
# @return [String]
|
103
|
+
def inspect
|
104
|
+
"#<E[#{element_id}]:#{display_name}>"
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the display name of the edge.
|
108
|
+
# @return [String]
|
109
|
+
def display_name
|
110
|
+
if graph and graph.edge_name
|
111
|
+
graph.edge_name.call self
|
112
|
+
else
|
113
|
+
"#{ out_vertex.element_id }-#{ getLabel }-#{ in_vertex.element_id }"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Deletes the edge from its graph.
|
118
|
+
def delete!
|
119
|
+
graph.remove_edge element
|
120
|
+
end
|
121
|
+
|
122
|
+
# Clones this edge into the target graph.
|
123
|
+
#
|
124
|
+
# This differs from the {#copy_into} in that it tries to set
|
125
|
+
# the new element_id the same as the original element_id.
|
126
|
+
#
|
127
|
+
# @param [PacerGraph] target_graph
|
128
|
+
# @param [Hash] opts
|
129
|
+
# @option opts :create_vertices [true] Create the vertices
|
130
|
+
# associated to this edge if they don't already exist.
|
131
|
+
# @yield [e] Optional block yields the edge after it has been created.
|
132
|
+
# @return [Pacer::Wrappers::EdgeWrapper] the new edge
|
133
|
+
#
|
134
|
+
# @raise [StandardError] If this the associated vertices don't exist and :create_vertices is not set
|
135
|
+
def clone_into(target_graph, opts = {})
|
136
|
+
e_idx = target_graph.index("tmp-e-#{graph.graph_id}", :edge, :create => true)
|
137
|
+
e = target_graph.edge(element_id)
|
138
|
+
unless e
|
139
|
+
e = e_idx.first('id', element_id)
|
140
|
+
if e
|
141
|
+
e = EdgeWrapper.new(e)
|
142
|
+
e.graph = target_graph
|
143
|
+
end
|
144
|
+
end
|
145
|
+
unless e
|
146
|
+
v_idx = target_graph.index("tmp-v-#{graph.graph_id}", :vertex, :create => true)
|
147
|
+
iv = target_graph.vertex(in_vertex.element_id) || v_idx.first('id', in_vertex.element_id)
|
148
|
+
ov = target_graph.vertex(out_vertex.element_id) || v_idx.first('id', out_vertex.element_id)
|
149
|
+
if opts[:create_vertices]
|
150
|
+
iv ||= in_vertex.clone_into target_graph
|
151
|
+
ov ||= out_vertex.clone_into target_graph
|
152
|
+
end
|
153
|
+
if not iv or not ov
|
154
|
+
message = "Vertex not found for #{ self.inspect }: #{ iv.inspect } -> #{ ov.inspect }"
|
155
|
+
puts message if opts[:show_missing_vertices]
|
156
|
+
raise message unless opts[:ignore_missing_vertices]
|
157
|
+
return nil
|
158
|
+
end
|
159
|
+
e = target_graph.create_edge(element_id, iv, ov, label, properties)
|
160
|
+
e_idx.put('id', element_id, e)
|
161
|
+
yield e if block_given?
|
162
|
+
end
|
163
|
+
e
|
164
|
+
end
|
165
|
+
|
166
|
+
# Copies this edge into the target graph with the next available
|
167
|
+
# edge id.
|
168
|
+
#
|
169
|
+
# @param [PacerGraph] target_graph
|
170
|
+
# @yield [e] Optional block yields the edge after it has been created.
|
171
|
+
# @return [Pacer::Wrappers::EdgeWrapper] the new edge
|
172
|
+
#
|
173
|
+
# @raise [StandardError] If this the associated vertices don't exist
|
174
|
+
def copy_into(target_graph)
|
175
|
+
v_idx = target_graph.index("tmp-v-#{graph.graph_id}", :vertex, :create => true)
|
176
|
+
iv = v_idx.first('id', in_vertex.element_id) || target_graph.vertex(in_vertex.element_id)
|
177
|
+
ov = v_idx.first('id', out_vertex.element_id) || target_graph.vertex(out_vertex.element_id)
|
178
|
+
|
179
|
+
raise 'vertices not found' if not iv or not ov
|
180
|
+
e = target_graph.create_edge nil, iv, ov, label, properties
|
181
|
+
yield e if block_given?
|
182
|
+
e
|
183
|
+
end
|
184
|
+
|
185
|
+
# Test equality to another object.
|
186
|
+
#
|
187
|
+
# Elements are equal if they are the same element type and have the same id
|
188
|
+
# and the same graph, regardless of extensions/wrappers.
|
189
|
+
#
|
190
|
+
# If the graphdb instantiates multiple copies of the same element
|
191
|
+
# this method will return true when comparing them.
|
192
|
+
#
|
193
|
+
# If the other instance is an unwrapped edge, this will always return
|
194
|
+
# false because otherwise the == method would not be symetrical.
|
195
|
+
#
|
196
|
+
# @see #eql?
|
197
|
+
# @param other
|
198
|
+
def ==(other)
|
199
|
+
other.is_a? EdgeWrapper and
|
200
|
+
element_id == other.element_id and
|
201
|
+
graph == other.graph
|
202
|
+
end
|
50
203
|
end
|
51
204
|
end
|
@@ -3,16 +3,26 @@ module Pacer::Wrappers
|
|
3
3
|
include Pacer::Element
|
4
4
|
extend Forwardable
|
5
5
|
include Comparable
|
6
|
+
include Pacer::Routes::RouteOperations
|
7
|
+
include Pacer::Core::Graph::ElementRoute
|
6
8
|
|
7
9
|
class << self
|
8
10
|
def wrap(element, exts)
|
9
|
-
|
11
|
+
if element.respond_to? :element
|
12
|
+
wrapper_for(exts).new(element.element)
|
13
|
+
else
|
14
|
+
wrapper_for(exts).new(element)
|
15
|
+
end
|
10
16
|
end
|
11
17
|
|
12
18
|
def extensions
|
13
19
|
@extensions ||= []
|
14
20
|
end
|
15
21
|
|
22
|
+
def add_extensions(exts)
|
23
|
+
wrapper_for(extensions + exts.to_a)
|
24
|
+
end
|
25
|
+
|
16
26
|
def clear_cache
|
17
27
|
Pacer.send :remove_const, :Wrap if Pacer.const_defined? :Wrap
|
18
28
|
VertexWrapper.clear_cache
|
@@ -37,8 +47,19 @@ module Pacer::Wrappers
|
|
37
47
|
sc_name = superclass.to_s.split(/::/).last
|
38
48
|
exts = exts.uniq unless exts.is_a? Set
|
39
49
|
classname = "#{sc_name}#{exts.map { |m| m.to_s }.join('')}".gsub(/::/, '_').gsub(/\W/, '')
|
40
|
-
|
41
|
-
|
50
|
+
begin
|
51
|
+
wrapper = Pacer::Wrap.const_get classname
|
52
|
+
rescue NameError
|
53
|
+
eval %{
|
54
|
+
module ::Pacer
|
55
|
+
module Wrap
|
56
|
+
class #{classname.to_s} < #{sc_name}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
}
|
61
|
+
wrapper = Pacer::Wrap.const_get classname
|
62
|
+
end
|
42
63
|
exts.each do |obj|
|
43
64
|
if obj.is_a? Module or obj.is_a? Class
|
44
65
|
mod_names.each do |mod_name|
|
@@ -53,21 +74,125 @@ module Pacer::Wrappers
|
|
53
74
|
end
|
54
75
|
end
|
55
76
|
|
77
|
+
# For internal use only.
|
78
|
+
#
|
79
|
+
# The graph the element belongs to.
|
80
|
+
#
|
81
|
+
# Used to help prevent objects from different graphs from being
|
82
|
+
# accidentally associated, as well as to get graph-specific data for
|
83
|
+
# the element.
|
84
|
+
#
|
85
|
+
# @return [PacerGraph]
|
86
|
+
attr_accessor :graph
|
87
|
+
attr_reader :element
|
88
|
+
|
56
89
|
def initialize(element)
|
57
|
-
|
90
|
+
if element.is_a? ElementWrapper
|
91
|
+
@element = element.element
|
92
|
+
else
|
93
|
+
@element = element
|
94
|
+
end
|
58
95
|
after_initialize
|
59
96
|
end
|
60
97
|
|
98
|
+
def hash
|
99
|
+
element.hash
|
100
|
+
end
|
101
|
+
|
102
|
+
# Convenience method to retrieve a property by name.
|
103
|
+
#
|
104
|
+
# @param [#to_s] key the property name
|
105
|
+
# @return [Object]
|
106
|
+
def [](key)
|
107
|
+
if key.is_a? Array
|
108
|
+
key.map { |k| self[k] }
|
109
|
+
else
|
110
|
+
value = element.getProperty(key.to_s)
|
111
|
+
graph.decode_property(value)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Convenience method to set a property by name to the given value.
|
116
|
+
# @param [#to_s] key the property name
|
117
|
+
# @param [Object] value the value to set the property to
|
118
|
+
def []=(key, value)
|
119
|
+
value = graph.encode_property(value)
|
120
|
+
key = key.to_s
|
121
|
+
if value
|
122
|
+
if value != element.getProperty(key)
|
123
|
+
element.setProperty(key, value)
|
124
|
+
end
|
125
|
+
else
|
126
|
+
element.removeProperty(key) if element.getPropertyKeys.include? key
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Specialize result to return self for elements.
|
131
|
+
# @return [ElementWrapper] self
|
132
|
+
def result(name = nil)
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
# Query whether the current node belongs to the given graph.
|
137
|
+
#
|
138
|
+
# @param [Object] g the object to compare to {#graph}
|
139
|
+
def from_graph?(g)
|
140
|
+
g.blueprints_graph.equal? graph.blueprints_graph
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns a hash of property values by name.
|
144
|
+
#
|
145
|
+
# @return [Hash]
|
146
|
+
def properties
|
147
|
+
element.getPropertyKeys.inject({}) { |h, name| h[name] = element.getProperty(name); h }
|
148
|
+
end
|
149
|
+
|
150
|
+
# Replace the element's properties with the given hash
|
151
|
+
#
|
152
|
+
# @param [Hash] props the element's new properties
|
153
|
+
def properties=(props)
|
154
|
+
(element.getPropertyKeys - props.keys.collect { |k| k.to_s }).each do |key|
|
155
|
+
element.removeProperty key
|
156
|
+
end
|
157
|
+
props.each do |key, value|
|
158
|
+
self[key] = value
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def property_keys
|
163
|
+
getPropertyKeys
|
164
|
+
end
|
165
|
+
|
166
|
+
# The id of the current element
|
167
|
+
# @return [Object] element id (type varies by graph implementation.
|
61
168
|
def element_id
|
62
|
-
|
169
|
+
element.getId
|
63
170
|
end
|
64
171
|
|
65
|
-
|
66
|
-
|
172
|
+
# Sort objects semi arbitrarily based on {#display_name}.
|
173
|
+
# @param other
|
174
|
+
#
|
175
|
+
# @return [Fixnum]
|
176
|
+
def <=>(other)
|
177
|
+
display_name.to_s <=> other.display_name.to_s
|
67
178
|
end
|
68
179
|
|
180
|
+
# Test object equality of the element instance.
|
181
|
+
#
|
182
|
+
# Wrappers/extensions (if any) are ignored, the underlying element
|
183
|
+
# only is compared
|
184
|
+
#
|
185
|
+
# If the graphdb instantiates multiple copies of the same element
|
186
|
+
# this method will return false when comparing them.
|
187
|
+
#
|
188
|
+
# @see #==
|
189
|
+
# @param other
|
69
190
|
def eql?(other)
|
70
|
-
|
191
|
+
if other.respond_to? :element_id
|
192
|
+
other.graph == graph and other.element_id == element_id
|
193
|
+
else
|
194
|
+
element.equals other
|
195
|
+
end
|
71
196
|
end
|
72
197
|
|
73
198
|
protected
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Pacer::Wrappers
|
2
|
+
class IndexWrapper
|
3
|
+
attr_reader :index, :graph, :element_type
|
4
|
+
|
5
|
+
def initialize(graph, index, element_type)
|
6
|
+
@index = index
|
7
|
+
@graph = graph
|
8
|
+
@element_type = element_type
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
index.index_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def wrapper
|
16
|
+
WrapperSelector.build element_type
|
17
|
+
end
|
18
|
+
|
19
|
+
def first(key, value, extensions = nil)
|
20
|
+
e = index.get(key, value).first
|
21
|
+
if e
|
22
|
+
e = wrapper.new e
|
23
|
+
e = e.add_extensions extensions if extensions
|
24
|
+
e.graph = graph
|
25
|
+
end
|
26
|
+
e
|
27
|
+
end
|
28
|
+
|
29
|
+
def all(key, value, extensions = nil)
|
30
|
+
iter = index.get(key, value)
|
31
|
+
if graph or extensions
|
32
|
+
pipe = Pacer::Pipes::WrappingPipe.new graph, element_type, extensions
|
33
|
+
pipe.setStarts iter.iterator
|
34
|
+
pipe
|
35
|
+
else
|
36
|
+
iter
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def put(key, value, element)
|
41
|
+
if element.is_a? ElementWrapper
|
42
|
+
element = element.element
|
43
|
+
end
|
44
|
+
index.put key, value, element
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -2,19 +2,20 @@ module Pacer::Wrappers
|
|
2
2
|
class VertexWrapper < ElementWrapper
|
3
3
|
include Pacer::Vertex
|
4
4
|
include Pacer::Core::Graph::VerticesRoute
|
5
|
-
include Pacer::ElementMixin
|
6
|
-
include Pacer::VertexMixin
|
7
5
|
|
8
6
|
def_delegators :@element,
|
9
7
|
:getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty,
|
10
|
-
:
|
11
|
-
:getRawVertex
|
12
|
-
:graph, :graph=, :<=>, :==
|
8
|
+
:getEdges,
|
9
|
+
:getRawVertex
|
13
10
|
|
14
11
|
class << self
|
15
12
|
def wrapper_for(exts)
|
16
13
|
@wrappers = {} unless defined? @wrappers
|
17
|
-
|
14
|
+
if exts
|
15
|
+
@wrappers[exts.to_set] ||= build_vertex_wrapper(exts)
|
16
|
+
else
|
17
|
+
fail Pacer::LogicError, "Extensions should not be nil"
|
18
|
+
end
|
18
19
|
end
|
19
20
|
|
20
21
|
def clear_cache
|
@@ -30,22 +31,184 @@ module Pacer::Wrappers
|
|
30
31
|
|
31
32
|
# This method must be defined here rather than in the superclass in order
|
32
33
|
# to correctly override the method in an included module
|
33
|
-
|
34
|
-
self.class.extensions
|
35
|
-
end
|
34
|
+
attr_reader :element
|
36
35
|
|
37
36
|
# This method must be defined here rather than in the superclass in order
|
38
37
|
# to correctly override the method in an included module
|
39
|
-
def
|
40
|
-
|
38
|
+
def extensions
|
39
|
+
self.class.extensions
|
41
40
|
end
|
42
41
|
|
42
|
+
# Add extensions to this vertex.
|
43
|
+
#
|
44
|
+
# If any extension has a Vertex module within it, this vertex will
|
45
|
+
# be extended with the extension's Vertex module.
|
46
|
+
#
|
47
|
+
# @param [[extensions]] exts the extensions to add
|
48
|
+
# @return [Pacer::EdgeWrapper] this vertex wrapped up and including
|
49
|
+
# the extensions
|
43
50
|
def add_extensions(exts)
|
44
51
|
if exts.any?
|
45
|
-
self.class.wrap(element, extensions + exts.to_a)
|
52
|
+
e = self.class.wrap(element, extensions + exts.to_a)
|
53
|
+
e.graph = graph
|
54
|
+
e
|
46
55
|
else
|
47
56
|
self
|
48
57
|
end
|
49
58
|
end
|
59
|
+
|
60
|
+
# Returns the element with a new simple wrapper.
|
61
|
+
# @return [VertexWrapper]
|
62
|
+
def no_extensions
|
63
|
+
e = VertexWrapper.new element
|
64
|
+
e.graph = graph
|
65
|
+
e
|
66
|
+
end
|
67
|
+
|
68
|
+
# Checks that the given extensions can be applied to the vertex. If
|
69
|
+
# they can then yield the vertex correctly extended or return the extended
|
70
|
+
# vertex. If not then do not yield and return nil.
|
71
|
+
#
|
72
|
+
# @param [extensions] exts extensions to add if possible
|
73
|
+
# @yield [v] Optional block yields the vertex with the extensions added.
|
74
|
+
# @return nil or the result of the block or the extended vertex
|
75
|
+
def as(*exts)
|
76
|
+
if as?(*exts)
|
77
|
+
exts_to_add = extensions_missing(exts)
|
78
|
+
extended = exts_to_add.empty? ? self : add_extensions(exts_to_add)
|
79
|
+
if block_given?
|
80
|
+
yield extended
|
81
|
+
else
|
82
|
+
extended
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def only_as(*exts)
|
88
|
+
if as?(*exts)
|
89
|
+
extended = exts.empty? ? no_extensions : no_extensions.add_extensions(exts)
|
90
|
+
if block_given?
|
91
|
+
yield extended
|
92
|
+
else
|
93
|
+
extended
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def as?(*exts)
|
99
|
+
has_exts = extensions_missing(exts).all? do |ext|
|
100
|
+
if ext.respond_to? :route_conditions
|
101
|
+
ext.route_conditions.all? do |k, v|
|
102
|
+
self[k] == v
|
103
|
+
end
|
104
|
+
else
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns a human-readable representation of the vertex using the
|
111
|
+
# standard ruby console representation of an instantiated object.
|
112
|
+
# @return [String]
|
113
|
+
def inspect
|
114
|
+
"#<#{ ["V[#{element_id}]", display_name].compact.join(' ') }>"
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the display name of the vertex.
|
118
|
+
# @return [String]
|
119
|
+
def display_name
|
120
|
+
graph.vertex_name.call self if graph and graph.vertex_name
|
121
|
+
end
|
122
|
+
|
123
|
+
# Deletes the vertex from its graph along with all related edges.
|
124
|
+
def delete!
|
125
|
+
graph.remove_vertex element
|
126
|
+
end
|
127
|
+
|
128
|
+
# Copies including the vertex id unless a vertex with that id
|
129
|
+
# already exists.
|
130
|
+
# @param [PacerGraph] target_graph
|
131
|
+
# @param opts for compatibility with {Pacer::Wrappers::EdgeWrapper#clone_into}
|
132
|
+
# @yield [v] Optional block yields the vertex after it has been created.
|
133
|
+
# @return [Pacer::Wrappers::VertexWrapper] the new vertex
|
134
|
+
def clone_into(target_graph, opts = nil)
|
135
|
+
v_idx = target_graph.index("tmp-v-#{graph.graph_id}", :vertex, :create => true)
|
136
|
+
v = target_graph.vertex(element_id) || v_idx.first('id', element_id)
|
137
|
+
unless v
|
138
|
+
v = target_graph.create_vertex element_id, properties
|
139
|
+
v_idx.put('id', element_id, v.element)
|
140
|
+
yield v if block_given?
|
141
|
+
end
|
142
|
+
v
|
143
|
+
end
|
144
|
+
|
145
|
+
# Make a new copy of the element with the next available vertex id.
|
146
|
+
#
|
147
|
+
# @param [PacerGraph] target_graph
|
148
|
+
# @yield [v] Optional block yields the vertex after it has been created.
|
149
|
+
# @return [Pacer::Wrappers::VertexWrapper] the new vertex
|
150
|
+
def copy_into(target_graph)
|
151
|
+
v = target_graph.create_vertex properties
|
152
|
+
yield v if block_given?
|
153
|
+
v
|
154
|
+
end
|
155
|
+
|
156
|
+
def out_edges(*labels_and_extensions)
|
157
|
+
get_edges_helper Pacer::Pipes::OUT, *labels_and_extensions
|
158
|
+
end
|
159
|
+
|
160
|
+
def in_edges(*labels_and_extensions)
|
161
|
+
get_edges_helper Pacer::Pipes::IN, *labels_and_extensions
|
162
|
+
end
|
163
|
+
|
164
|
+
def both_edges(*labels_and_extensions)
|
165
|
+
get_edges_helper Pacer::Pipes::BOTH, *labels_and_extensions
|
166
|
+
end
|
167
|
+
|
168
|
+
# Test equality to another object.
|
169
|
+
#
|
170
|
+
# Elements are equal if they are the same type and have the same id
|
171
|
+
# and the same graph, regardless of extensions.
|
172
|
+
#
|
173
|
+
# If the graphdb instantiates multiple copies of the same element
|
174
|
+
# this method will return true when comparing them.
|
175
|
+
#
|
176
|
+
# If the other instance is an unwrapped vertex, this will always return
|
177
|
+
# false because otherwise the == method would not be symetrical.
|
178
|
+
#
|
179
|
+
# @see #eql?
|
180
|
+
# @param other
|
181
|
+
def ==(other)
|
182
|
+
other.is_a? VertexWrapper and
|
183
|
+
element_id == other.element_id and
|
184
|
+
graph == other.graph
|
185
|
+
end
|
186
|
+
|
187
|
+
protected
|
188
|
+
|
189
|
+
def get_edges_helper(direction, *labels_and_extensions)
|
190
|
+
labels, exts = split_labels_and_extensions(labels_and_extensions)
|
191
|
+
pipe = Pacer::Pipes::WrappingPipe.new graph, :edge, exts
|
192
|
+
pipe.setStarts element.getEdges(direction, *labels).iterator
|
193
|
+
pipe
|
194
|
+
end
|
195
|
+
|
196
|
+
def split_labels_and_extensions(mixed)
|
197
|
+
labels = Set[]
|
198
|
+
exts = []
|
199
|
+
mixed.each do |obj|
|
200
|
+
if obj.is_a? Symbol or obj.is_a? String
|
201
|
+
labels << obj
|
202
|
+
else
|
203
|
+
exts << obj
|
204
|
+
end
|
205
|
+
end
|
206
|
+
[labels, exts.uniq]
|
207
|
+
end
|
208
|
+
|
209
|
+
# Return the extensions this vertex is missing from the given array
|
210
|
+
def extensions_missing(exts)
|
211
|
+
Set.new(exts.flatten).difference extensions.to_set
|
212
|
+
end
|
50
213
|
end
|
51
214
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Pacer::Wrappers
|
2
|
+
class WrapperSelector
|
3
|
+
import com.tinkerpop.blueprints.Vertex
|
4
|
+
import com.tinkerpop.blueprints.Edge
|
5
|
+
|
6
|
+
def self.build(element_type = nil, extensions = [])
|
7
|
+
if element_type == :vertex
|
8
|
+
Pacer::Wrappers::VertexWrapper.wrapper_for extensions
|
9
|
+
elsif element_type == :edge
|
10
|
+
Pacer::Wrappers::EdgeWrapper.wrapper_for extensions
|
11
|
+
else
|
12
|
+
new extensions
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :extensions
|
17
|
+
attr_accessor :vertex_wrapper, :edge_wrapper
|
18
|
+
|
19
|
+
def initialize(extensions = [])
|
20
|
+
@extensions = extensions
|
21
|
+
end
|
22
|
+
|
23
|
+
def wrapper(element)
|
24
|
+
if element.is_a? Vertex
|
25
|
+
self.vertex_wrapper ||= Pacer::Wrappers::VertexWrapper.wrapper_for extensions
|
26
|
+
elsif element.is_a? Edge
|
27
|
+
self.edge_wrapper ||= Pacer::Wrappers::EdgeWrapper.wrapper_for extensions
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def new(element)
|
32
|
+
w = wrapper(element)
|
33
|
+
if w
|
34
|
+
w.new element
|
35
|
+
else
|
36
|
+
element
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|