neo4j 1.2.3-java → 1.2.4-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/CHANGELOG +6 -0
- data/README.rdoc +1 -1
- data/lib/neo4j/index/indexer.rb +20 -6
- data/lib/neo4j/neo4j.rb +0 -9
- data/lib/neo4j/node.rb +87 -1
- data/lib/neo4j/node_mixin/node_mixin.rb +1 -1
- data/lib/neo4j/rails/finders.rb +7 -3
- data/lib/neo4j/rails/mapping/property.rb +10 -0
- data/lib/neo4j/rails/model.rb +67 -0
- data/lib/neo4j/rails/persistence.rb +5 -5
- data/lib/neo4j/rails/{lucene_connection_closer.rb → rack_middleware.rb} +4 -1
- data/lib/neo4j/rails/rails.rb +1 -1
- data/lib/neo4j/rails/railtie.rb +1 -1
- data/lib/neo4j/rule/event_listener.rb +1 -3
- data/lib/neo4j/rule/rule.rb +0 -4
- data/lib/neo4j/rule/rule_node.rb +3 -7
- data/lib/neo4j/traversal/traversal.rb +51 -3
- data/lib/neo4j/traversal/traverser.rb +59 -0
- data/lib/neo4j/version.rb +1 -1
- data/lib/orm_adapter/adapters/neo4j.rb +11 -15
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 1.2.4 / 2011-10-07
|
2
|
+
* Support for traversing with Neo4j::Node#eval_paths and setting uniqueness on traversals [#187]
|
3
|
+
* Removed unnecessary node creation on database start up (class nodes attached to reference node) (Vivek Prahlad)
|
4
|
+
* Safer multitenancy - automatically reset the reference node in thread local context after each request using rack middleware
|
5
|
+
* Bugfixes for multitenancy (Deepak N and Vivek Prahlad)
|
6
|
+
|
1
7
|
== 1.2.3 / 2011-10-01
|
2
8
|
* Multitenancy support by namespaced-indices & changeable reference node (Vivek Prahlad, pull 41)
|
3
9
|
* Added a Neo4j::Rails::Model#columns which returns all defined properties [#186]
|
data/README.rdoc
CHANGED
@@ -45,7 +45,7 @@ Example of creating a Neo4j::Node
|
|
45
45
|
node.outgoing(:friends).each {|node| puts "name #{node[:name]}"}
|
46
46
|
end
|
47
47
|
|
48
|
-
==== Neo4j::
|
48
|
+
==== Neo4j::NodeMixin
|
49
49
|
|
50
50
|
Example of mapping a ruby class to a node and delaring properties and relationships and lucene index.
|
51
51
|
|
data/lib/neo4j/index/indexer.rb
CHANGED
@@ -267,8 +267,9 @@ module Neo4j
|
|
267
267
|
def delete_index_type(type=nil)
|
268
268
|
if type
|
269
269
|
#raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
|
270
|
-
|
271
|
-
@indexes[
|
270
|
+
key = index_key(type)
|
271
|
+
@indexes[key] && @indexes[key].delete
|
272
|
+
@indexes[key] = nil
|
272
273
|
else
|
273
274
|
@indexes.each_value { |index| index.delete }
|
274
275
|
@indexes.clear
|
@@ -293,11 +294,15 @@ module Neo4j
|
|
293
294
|
|
294
295
|
def index_for_field(field) #:nodoc:
|
295
296
|
type = @field_types[field]
|
296
|
-
create_index_with(type)
|
297
|
+
@indexes[index_key(type)] ||= create_index_with(type)
|
297
298
|
end
|
298
299
|
|
299
300
|
def index_for_type(type) #:nodoc:
|
300
|
-
create_index_with(type)
|
301
|
+
@indexes[index_key(type)] ||= create_index_with(type)
|
302
|
+
end
|
303
|
+
|
304
|
+
def index_key(type)
|
305
|
+
index_names[type] + type.to_s
|
301
306
|
end
|
302
307
|
|
303
308
|
def lucene_config(type) #:nodoc:
|
@@ -317,11 +322,20 @@ module Neo4j
|
|
317
322
|
end
|
318
323
|
|
319
324
|
def index_names
|
320
|
-
@index_names ||= Hash.new do |hash,index_type|
|
321
|
-
default_filename =
|
325
|
+
@index_names ||= Hash.new do |hash, index_type|
|
326
|
+
default_filename = index_prefix + @indexer_for.to_s.gsub('::', '_')
|
322
327
|
hash.fetch(index_type) {"#{default_filename}-#{index_type}"}
|
323
328
|
end
|
324
329
|
end
|
330
|
+
|
331
|
+
protected
|
332
|
+
def index_prefix
|
333
|
+
return "" unless Neo4j.running?
|
334
|
+
return "" unless @indexer_for.respond_to?(:ref_node_for_class)
|
335
|
+
ref_node = @indexer_for.ref_node_for_class
|
336
|
+
ref_node_name = ref_node[:name]
|
337
|
+
ref_node_name.blank? ? "" : ref_node_name + "_"
|
338
|
+
end
|
325
339
|
end
|
326
340
|
end
|
327
341
|
end
|
data/lib/neo4j/neo4j.rb
CHANGED
@@ -150,15 +150,6 @@ module Neo4j
|
|
150
150
|
Thread.current[:local_ref_node] = reference_node.nil? ? nil : reference_node._java_node
|
151
151
|
end
|
152
152
|
|
153
|
-
# Returns a prefix for lucene indices based on the name property of the current reference node.
|
154
|
-
# This allows the index names to be prefixed by the reference node name, and hence scopes lucene indexes
|
155
|
-
# to all entities under the current reference node.
|
156
|
-
def index_prefix
|
157
|
-
return "" if not running?
|
158
|
-
ref_node_name = ref_node[:name]
|
159
|
-
ref_node_name.nil? || ref_node_name.empty? ? "" : ref_node_name + "_"
|
160
|
-
end
|
161
|
-
|
162
153
|
# Returns a Management JMX Bean.
|
163
154
|
#
|
164
155
|
# Notice that this information is also provided by the jconsole Java tool, check http://wiki.neo4j.org/content/Monitoring_and_Deployment
|
data/lib/neo4j/node.rb
CHANGED
@@ -113,7 +113,93 @@ module Neo4j
|
|
113
113
|
# :method: _java_node
|
114
114
|
# Returns the java node/relationship object representing this object unless it is already the java object.
|
115
115
|
# This method is defined in the org.neo4j.kernel.impl.core.NodeProxy which is return by Neo4j::Node.new
|
116
|
-
|
116
|
+
|
117
|
+
|
118
|
+
##
|
119
|
+
# :method: expand
|
120
|
+
# See Neo4j::Traversal#expand
|
121
|
+
|
122
|
+
##
|
123
|
+
# :method: outgoing
|
124
|
+
# See Neo4j::Traversal#outgoing
|
125
|
+
|
126
|
+
|
127
|
+
##
|
128
|
+
# :method: incoming
|
129
|
+
# See Neo4j::Traversal#incoming
|
130
|
+
|
131
|
+
##
|
132
|
+
# :method: both
|
133
|
+
# See Neo4j::Traversal#both
|
134
|
+
|
135
|
+
##
|
136
|
+
# :method: eval_paths
|
137
|
+
# See Neo4j::Traversal#eval_paths
|
138
|
+
|
139
|
+
##
|
140
|
+
# :method: unique
|
141
|
+
# See Neo4j::Traversal#unique
|
142
|
+
|
143
|
+
##
|
144
|
+
# :method: node
|
145
|
+
# See Neo4j::Rels#node or Neo4j::Rels
|
146
|
+
|
147
|
+
##
|
148
|
+
# :method: _node
|
149
|
+
# See Neo4j::Rels#_node or Neo4j::Rels
|
150
|
+
|
151
|
+
##
|
152
|
+
# :method: rels
|
153
|
+
# See Neo4j::Rels#rels or Neo4j::Rels
|
154
|
+
|
155
|
+
##
|
156
|
+
# :method: _rels
|
157
|
+
# See Neo4j::Rels#_rels or Neo4j::Rels
|
158
|
+
|
159
|
+
##
|
160
|
+
# :method: rel
|
161
|
+
# See Neo4j::Rels#rel
|
162
|
+
|
163
|
+
##
|
164
|
+
# :method: _rel
|
165
|
+
# See Neo4j::Rels#_rel
|
166
|
+
|
167
|
+
##
|
168
|
+
# :method: rel?
|
169
|
+
# See Neo4j::Rels#rel?
|
170
|
+
|
171
|
+
##
|
172
|
+
# :method: props
|
173
|
+
# See Neo4j::Property#props
|
174
|
+
|
175
|
+
##
|
176
|
+
# :method: neo_id
|
177
|
+
# See Neo4j::Property#neo_id
|
178
|
+
|
179
|
+
##
|
180
|
+
# :method: attributes
|
181
|
+
# See Neo4j::Property#attributes
|
182
|
+
|
183
|
+
##
|
184
|
+
# :method: property?
|
185
|
+
# See Neo4j::Property#property?
|
186
|
+
|
187
|
+
##
|
188
|
+
# :method: update
|
189
|
+
# See Neo4j::Property#update
|
190
|
+
|
191
|
+
##
|
192
|
+
# :method: []
|
193
|
+
# See Neo4j::Property#[]
|
194
|
+
|
195
|
+
##
|
196
|
+
# :method: []=
|
197
|
+
# See Neo4j::Property#[]=
|
198
|
+
|
199
|
+
##
|
200
|
+
# :method: []=
|
201
|
+
# See Neo4j::Property#[]=
|
202
|
+
|
117
203
|
class << self
|
118
204
|
|
119
205
|
# Returns a new neo4j Node.
|
@@ -15,7 +15,7 @@ require 'neo4j/node_mixin/class_methods'
|
|
15
15
|
module Neo4j
|
16
16
|
# This Mixin is used to wrap Neo4j Java Nodes in Ruby objects.
|
17
17
|
#
|
18
|
-
# It includes a number of mixins and forwards some methods to the raw Java node which
|
18
|
+
# It includes a number of mixins and forwards some methods to the raw Java node (Neo4j::Node) which includes the mixins below:
|
19
19
|
#
|
20
20
|
# === Instance Methods
|
21
21
|
#
|
data/lib/neo4j/rails/finders.rb
CHANGED
@@ -73,7 +73,7 @@ module Neo4j
|
|
73
73
|
when :all, :first
|
74
74
|
kind = args.shift
|
75
75
|
send(kind, *args)
|
76
|
-
when "0", 0
|
76
|
+
when "0", 0, nil
|
77
77
|
nil
|
78
78
|
else
|
79
79
|
if ((args.first.is_a?(Integer) || args.first.is_a?(String)) && args.first.to_i > 0)
|
@@ -189,13 +189,17 @@ module Neo4j
|
|
189
189
|
def find_with_ids(*args)
|
190
190
|
result = load(*args.map { |p| p.to_i })
|
191
191
|
if result.is_a?(Array)
|
192
|
-
result = result.select { |r| r
|
192
|
+
result = result.select { |r| findable?(r)}
|
193
193
|
else
|
194
|
-
result = nil unless result
|
194
|
+
result = nil unless findable?(result)
|
195
195
|
end
|
196
196
|
result
|
197
197
|
end
|
198
198
|
|
199
|
+
def findable?(entity)
|
200
|
+
entity.is_a? self
|
201
|
+
end
|
202
|
+
|
199
203
|
def find_with_indexer(*args)
|
200
204
|
hits = _indexer.find(*args)
|
201
205
|
# We need to save this so that the Rack Neo4j::Rails:LuceneConnection::Closer can close it
|
@@ -75,6 +75,16 @@ module Neo4j
|
|
75
75
|
RUBY
|
76
76
|
end
|
77
77
|
|
78
|
+
unless method_defined?("#{rel_type}=".to_sym)
|
79
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
80
|
+
def #{rel_type}=(nodes)
|
81
|
+
self.#{rel_type}_rels.destroy_all
|
82
|
+
association = self.#{rel_type}
|
83
|
+
nodes.each { |node| association << node }
|
84
|
+
end
|
85
|
+
RUBY
|
86
|
+
end
|
87
|
+
|
78
88
|
unless method_defined?("#{rel_type}_rels".to_sym)
|
79
89
|
class_eval <<-RUBY, __FILE__, __LINE__
|
80
90
|
def #{rel_type}_rels
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -91,6 +91,68 @@ module Neo4j
|
|
91
91
|
new? ? self.__id__ == other.__id__ : @_java_node == (other)
|
92
92
|
end
|
93
93
|
|
94
|
+
def reachable_from_ref_node?
|
95
|
+
Neo4j::Algo.all_path(self.class.ref_node_for_class, self).outgoing(self.class).outgoing(:_all).count > 0
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# :method: outgoing
|
100
|
+
#
|
101
|
+
# Similar to Neo4j::Traversal#outgoing but returns depth one only outgoing relationship
|
102
|
+
# which may not all be persisted.
|
103
|
+
# For only traversing persisted outgoing relationship of any depth or more advanced traversals, use
|
104
|
+
# the wrapped Java node instead.
|
105
|
+
#
|
106
|
+
# ==== Examples
|
107
|
+
#
|
108
|
+
# person.outgoing(:friends) << other_person
|
109
|
+
# person.save!
|
110
|
+
#
|
111
|
+
# person.outgoing(:friends).map{|f| f.outgoing(:knows).to_a}.flatten
|
112
|
+
#
|
113
|
+
# ==== Examples
|
114
|
+
#
|
115
|
+
# Neo4j::Transaction.run do
|
116
|
+
# person._java_node.outgoing(:friends) << other_person
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# person._java_node.outgoing(:friends).outgoing(:knows).depth(4)
|
120
|
+
#
|
121
|
+
# Notice you can also declare outgoing relationships with the #has_n and #has_one class method.
|
122
|
+
#
|
123
|
+
# See Neo4j::Rails::Relationships#outgoing
|
124
|
+
# See Neo4j::Traversal#outgoing (when using it from the _java_node)
|
125
|
+
|
126
|
+
|
127
|
+
##
|
128
|
+
# :method: incoming
|
129
|
+
#
|
130
|
+
# Returns incoming relationship of depth one which may not all be persisted.
|
131
|
+
# See #outgoing
|
132
|
+
|
133
|
+
|
134
|
+
##
|
135
|
+
# :method: rels
|
136
|
+
#
|
137
|
+
# Returns both incoming and outgoing relationships which may not all be persisted.
|
138
|
+
# If you only want to find persisted relationships: @node._java_node.rels@
|
139
|
+
#
|
140
|
+
# See Neo4j::Rails::Relationships#rels
|
141
|
+
# See Neo4j::Rels#rels or Neo4j::Rels
|
142
|
+
#
|
143
|
+
|
144
|
+
##
|
145
|
+
# :method: []
|
146
|
+
#
|
147
|
+
# Returns a property of this node, which may or may not have been declared with the class property method.
|
148
|
+
# Similar to Neo4j::Property#[] but can return not persisted properties as well.
|
149
|
+
|
150
|
+
##
|
151
|
+
# :method: []=
|
152
|
+
#
|
153
|
+
# Sets any property on the node.
|
154
|
+
# Similar to Neo4j::Property#[]= but you must call the #save method to persist the property.
|
155
|
+
|
94
156
|
##
|
95
157
|
# :singleton-method: property
|
96
158
|
#
|
@@ -179,6 +241,11 @@ module Neo4j
|
|
179
241
|
end
|
180
242
|
end
|
181
243
|
|
244
|
+
# When multitenancy is used, node should be findable only from current ref node.
|
245
|
+
def findable?(entity)
|
246
|
+
entity.is_a? self and entity.reachable_from_ref_node?
|
247
|
+
end
|
248
|
+
|
182
249
|
# Set the i18n scope to overwrite ActiveModel.
|
183
250
|
#
|
184
251
|
# @return [ Symbol ] :neo4j
|
@@ -204,9 +204,9 @@ module Neo4j
|
|
204
204
|
end
|
205
205
|
|
206
206
|
def _add_relationship(rel_type, node)
|
207
|
-
if respond_to?("#{rel_type}
|
207
|
+
if respond_to?("#{rel_type}_rel")
|
208
208
|
send("#{rel_type}=", node)
|
209
|
-
elsif respond_to?("#{rel_type}")
|
209
|
+
elsif respond_to?("#{rel_type}_rels")
|
210
210
|
has_n = send("#{rel_type}")
|
211
211
|
has_n << node
|
212
212
|
else
|
@@ -216,9 +216,9 @@ module Neo4j
|
|
216
216
|
|
217
217
|
def _find_node(rel_type, id)
|
218
218
|
return nil if id.nil?
|
219
|
-
if respond_to?("#{rel_type}
|
219
|
+
if respond_to?("#{rel_type}_rel")
|
220
220
|
send("#{rel_type}")
|
221
|
-
elsif respond_to?("#{rel_type}")
|
221
|
+
elsif respond_to?("#{rel_type}_rels")
|
222
222
|
has_n = send("#{rel_type}")
|
223
223
|
has_n.find { |n| n.id == id }
|
224
224
|
else
|
@@ -235,7 +235,7 @@ module Neo4j
|
|
235
235
|
begin
|
236
236
|
# Check if we want to destroy not found nodes (e.g. {..., :_destroy => '1' } ?
|
237
237
|
destroy = allow_destroy && attr[:_destroy] && attr[:_destroy] != '0'
|
238
|
-
found = _find_node(rel_type, attr[:id]) ||
|
238
|
+
found = _find_node(rel_type, attr[:id]) || Model.find(attr[:id])
|
239
239
|
if destroy
|
240
240
|
found.destroy if found
|
241
241
|
else
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
-
|
3
|
+
# close lucene connections
|
4
|
+
# reset the Neo4j.threadlocal_ref_node (Multitenancy)
|
5
|
+
class RackMiddleware #:nodoc:
|
4
6
|
def initialize(app)
|
5
7
|
@app = app
|
6
8
|
end
|
@@ -9,6 +11,7 @@ module Neo4j
|
|
9
11
|
@app.call(env)
|
10
12
|
ensure
|
11
13
|
Neo4j::Rails::Model.close_lucene_connections
|
14
|
+
Neo4j.threadlocal_ref_node = Neo4j.default_ref_node
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
data/lib/neo4j/rails/rails.rb
CHANGED
@@ -20,6 +20,6 @@ require 'neo4j/rails/relationships/node_dsl'
|
|
20
20
|
require 'neo4j/rails/relationships/rels_dsl'
|
21
21
|
require 'neo4j/rails/relationships/relationships'
|
22
22
|
require 'neo4j/rails/model'
|
23
|
-
require 'neo4j/rails/
|
23
|
+
require 'neo4j/rails/rack_middleware'
|
24
24
|
require 'neo4j/rails/rel_persistence'
|
25
25
|
require 'neo4j/rails/relationship'
|
data/lib/neo4j/rails/railtie.rb
CHANGED
@@ -3,7 +3,7 @@ module Neo4j
|
|
3
3
|
config.neo4j = ActiveSupport::OrderedOptions.new
|
4
4
|
|
5
5
|
initializer "neo4j.tx" do |app|
|
6
|
-
app.config.middleware.use Neo4j::Rails::
|
6
|
+
app.config.middleware.use Neo4j::Rails::RackMiddleware
|
7
7
|
end
|
8
8
|
|
9
9
|
# Add ActiveModel translations to the I18n load_path
|
data/lib/neo4j/rule/rule.rb
CHANGED
@@ -90,10 +90,6 @@ module Neo4j
|
|
90
90
|
@rule_nodes && @rule_nodes.values.find { |rn| rn.rule_node?(node) }
|
91
91
|
end
|
92
92
|
|
93
|
-
def on_neo4j_started
|
94
|
-
@rule_nodes.each_value { |rule_node| rule_node.on_neo4j_started } if @rule_nodes
|
95
|
-
end
|
96
|
-
|
97
93
|
def inherit(parent_class, subclass)
|
98
94
|
# copy all the rules
|
99
95
|
if rule_node = rule_node_for(parent_class)
|
data/lib/neo4j/rule/rule_node.rb
CHANGED
@@ -15,6 +15,7 @@ module Neo4j
|
|
15
15
|
@clazz = clazz
|
16
16
|
@rules = []
|
17
17
|
@rule_node_key = ("rule_" + clazz.to_s).to_sym
|
18
|
+
@ref_node_key = ("rule_ref_for_" + clazz.to_s).to_sym
|
18
19
|
end
|
19
20
|
|
20
21
|
def to_s
|
@@ -59,19 +60,14 @@ module Neo4j
|
|
59
60
|
ref_node.rel?(@clazz.to_s) && ref_node._rel(:outgoing, @clazz.to_s)._end_node
|
60
61
|
end
|
61
62
|
|
62
|
-
def on_neo4j_started
|
63
|
-
# initialize the rule node when neo4j starts
|
64
|
-
Thread.current[@rule_node_key] = find_node || create_node
|
65
|
-
end
|
66
|
-
|
67
63
|
def rule_node
|
68
64
|
clear_rule_node if ref_node_changed?
|
69
65
|
Thread.current[@rule_node_key] ||= find_node || create_node
|
70
66
|
end
|
71
67
|
|
72
68
|
def ref_node_changed?
|
73
|
-
if ref_node != Thread.current[
|
74
|
-
Thread.current[
|
69
|
+
if ref_node != Thread.current[@ref_node_key]
|
70
|
+
Thread.current[@ref_node_key] = ref_node
|
75
71
|
true
|
76
72
|
else
|
77
73
|
false
|
@@ -4,6 +4,11 @@ require 'neo4j/traversal/rel_expander'
|
|
4
4
|
require 'neo4j/traversal/traverser'
|
5
5
|
|
6
6
|
module Neo4j
|
7
|
+
|
8
|
+
# Contains methods that are mixin for Neo4j::Node
|
9
|
+
# They all return Neo4j::Traversal::Traverser
|
10
|
+
# See the {Neo4j.rb Guide: Traversing Relationships and Nodes}[http://neo4j.rubyforge.org/guides/traverser.html]
|
11
|
+
#
|
7
12
|
module Traversal
|
8
13
|
include ToJava
|
9
14
|
|
@@ -16,6 +21,8 @@ module Neo4j
|
|
16
21
|
#
|
17
22
|
# The above traverse all relationships with a property of age > 5
|
18
23
|
#
|
24
|
+
# See http://neo4j.rubyforge.org/guides/traverser.html
|
25
|
+
#
|
19
26
|
def expand(&expander)
|
20
27
|
Traverser.new(self).expander(&expander)
|
21
28
|
end
|
@@ -49,7 +56,9 @@ module Neo4j
|
|
49
56
|
# # Find all my friends and work colleges
|
50
57
|
# me.outgoing(:friends).outgoing(:work).each {...}
|
51
58
|
#
|
52
|
-
# Of course all the methods <tt>outgoing</tt>, <tt>incoming</tt>, <tt>both</tt>, <tt>depth</tt>, <tt>include_start_node</tt>, <tt>filter</tt>, and <tt>prune</tt> can be combined.
|
59
|
+
# Of course all the methods <tt>outgoing</tt>, <tt>incoming</tt>, <tt>both</tt>, <tt>depth</tt>, <tt>include_start_node</tt>, <tt>filter</tt>, and <tt>prune</tt>, <tt>eval_paths</tt>, <tt>unique</tt> can be combined.
|
60
|
+
#
|
61
|
+
# See the {Neo4j.rb Guides}[http://neo4j.rubyforge.org/guides/traverser.html]
|
53
62
|
#
|
54
63
|
def outgoing(type)
|
55
64
|
if type
|
@@ -62,7 +71,7 @@ module Neo4j
|
|
62
71
|
|
63
72
|
# Returns the incoming nodes of given type(s).
|
64
73
|
#
|
65
|
-
# See #outgoing
|
74
|
+
# See #outgoing and http://neo4j.rubyforge.org/guides/traverser.html
|
66
75
|
#
|
67
76
|
def incoming(type)
|
68
77
|
if type
|
@@ -76,7 +85,7 @@ module Neo4j
|
|
76
85
|
#
|
77
86
|
# If a type is not given then it will return all types of relationships.
|
78
87
|
#
|
79
|
-
# See #outgoing
|
88
|
+
# See #outgoing and http://neo4j.rubyforge.org/guides/traverser.html
|
80
89
|
#
|
81
90
|
def both(type=nil)
|
82
91
|
if type
|
@@ -86,5 +95,44 @@ module Neo4j
|
|
86
95
|
end
|
87
96
|
end
|
88
97
|
|
98
|
+
|
99
|
+
# Traverse using a block. The block is expected to return one of the following values:
|
100
|
+
# * <tt>:exclude_and_continue</tt>
|
101
|
+
# * <tt>:exclude_and_prune</tt>
|
102
|
+
# * <tt>:include_and_continue</tt>
|
103
|
+
# * <tt>:include_and_prune</tt>
|
104
|
+
# This value decides if it should continue to traverse and if it should include the node in the traversal result.
|
105
|
+
# The block will receive a path argument.
|
106
|
+
#
|
107
|
+
# ==== Example
|
108
|
+
#
|
109
|
+
# @pet0.eval_paths {|path| path.end_node == @principal1 ? :include_and_prune : :exclude_and_continue }.unique(:node_path).depth(:all)
|
110
|
+
#
|
111
|
+
# ==== See also
|
112
|
+
#
|
113
|
+
# * How to use - http://neo4j.rubyforge.org/guides/traverser.html
|
114
|
+
# * the path parameter - http://api.neo4j.org/1.4/org/neo4j/graphdb/Path.html
|
115
|
+
# * the #unique method - if paths should be visit more the once, etc...
|
116
|
+
#
|
117
|
+
def eval_paths(&eval_block)
|
118
|
+
Traverser.new(self).eval_paths(&eval_block)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Sets uniqueness of nodes or relationships to visit during a traversals.
|
122
|
+
#
|
123
|
+
# Allowed values
|
124
|
+
# * <tt>:node_global</tt> A node cannot be traversed more than once (default)
|
125
|
+
# * <tt>:node_path</tt> For each returned node there 's a unique path from the start node to it.
|
126
|
+
# * <tt>:node_recent</tt> This is like :node_global, but only guarantees uniqueness among the most recent visited nodes, with a configurable count.
|
127
|
+
# * <tt>:none</tt> No restriction (the user will have to manage it).
|
128
|
+
# * <tt>:rel_global</tt> A relationship cannot be traversed more than once, whereas nodes can.
|
129
|
+
# * <tt>:rel_path</tt> :: No restriction (the user will have to manage it).
|
130
|
+
# * <tt>:rel_recent</tt> Same as for :node_recent, but for relationships.
|
131
|
+
#
|
132
|
+
# See example in #eval_paths
|
133
|
+
# See http://api.neo4j.org/1.4/org/neo4j/kernel/Uniqueness.html and http://neo4j.rubyforge.org/guides/traverser.html
|
134
|
+
def unique(u)
|
135
|
+
Traverser.new(self).unique(u)
|
136
|
+
end
|
89
137
|
end
|
90
138
|
end
|
@@ -2,6 +2,32 @@ module Neo4j
|
|
2
2
|
|
3
3
|
module Traversal
|
4
4
|
|
5
|
+
class Evaluator #:nodoc:
|
6
|
+
include org.neo4j.graphdb.traversal.Evaluator
|
7
|
+
def initialize(&eval_block)
|
8
|
+
@eval_block = eval_block
|
9
|
+
end
|
10
|
+
|
11
|
+
# Implements the Java Interface:
|
12
|
+
# evaluate(Path path)
|
13
|
+
# Evaluates a Path and returns an Evaluation containing information about whether or not to include it in the traversal result, i.e return it from the Traverser.
|
14
|
+
def evaluate(path)
|
15
|
+
ret = @eval_block.call(path)
|
16
|
+
case ret
|
17
|
+
when :exclude_and_continue then
|
18
|
+
org.neo4j.graphdb.traversal.Evaluation::EXCLUDE_AND_CONTINUE
|
19
|
+
when :exclude_and_prune then
|
20
|
+
org.neo4j.graphdb.traversal.Evaluation::EXCLUDE_AND_PRUNE
|
21
|
+
when :include_and_continue then
|
22
|
+
org.neo4j.graphdb.traversal.Evaluation::INCLUDE_AND_CONTINUE
|
23
|
+
when :include_and_prune then
|
24
|
+
org.neo4j.graphdb.traversal.Evaluation::INCLUDE_AND_PRUNE
|
25
|
+
else
|
26
|
+
raise "Got #{ret}, only accept :exclude_and_continue,:exclude_and_prune,:include_and_continue and :include_and_prune"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
5
31
|
class Traverser
|
6
32
|
include Enumerable
|
7
33
|
include ToJava
|
@@ -20,6 +46,39 @@ module Neo4j
|
|
20
46
|
end
|
21
47
|
end
|
22
48
|
|
49
|
+
def eval_paths(&eval_path_block)
|
50
|
+
@td = @td.evaluator(Evaluator.new(&eval_path_block))
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def unique(u = :node_global)
|
55
|
+
case u
|
56
|
+
when :node_global then
|
57
|
+
# A node cannot be traversed more than once.
|
58
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::NODE_GLOBAL)
|
59
|
+
when :node_path then
|
60
|
+
# For each returned node there 's a unique path from the start node to it.
|
61
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::NODE_PATH)
|
62
|
+
when :node_recent then
|
63
|
+
# This is like NODE_GLOBAL, but only guarantees uniqueness among the most recent visited nodes, with a configurable count.
|
64
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::NODE_RECENT)
|
65
|
+
when :none then
|
66
|
+
# No restriction (the user will have to manage it).
|
67
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::NONE)
|
68
|
+
when :rel_global then
|
69
|
+
# A relationship cannot be traversed more than once, whereas nodes can.
|
70
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::RELATIONSHIP_GLOBAL)
|
71
|
+
when :rel_path then
|
72
|
+
# No restriction (the user will have to manage it).
|
73
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::RELATIONSHIP_PATH)
|
74
|
+
when :rel_recent then
|
75
|
+
# Same as for NODE_RECENT, but for relationships.
|
76
|
+
@td = @td.uniqueness(org.neo4j.kernel.Uniqueness::RELATIONSHIP_RECENT)
|
77
|
+
else
|
78
|
+
raise "Got option for unique '#{u}' allowed: :node_global, :node_path, :node_recent, :none, :rel_global, :rel_path, :rel_recent"
|
79
|
+
end
|
80
|
+
self
|
81
|
+
end
|
23
82
|
|
24
83
|
def to_s
|
25
84
|
"NodeTraverser [from: #{@from.neo_id} depth: #{@depth} type: #{@type} dir:#{@dir}"
|
data/lib/neo4j/version.rb
CHANGED
@@ -4,50 +4,46 @@ module Neo4j
|
|
4
4
|
module Rails
|
5
5
|
class Model
|
6
6
|
extend ::OrmAdapter::ToAdapter
|
7
|
-
|
7
|
+
|
8
8
|
class OrmAdapter < ::OrmAdapter::Base
|
9
|
-
NEO4J_REF_NODE_ID = 0
|
10
|
-
|
11
9
|
# Do not consider these to be part of the class list
|
12
10
|
def self.except_classes
|
13
11
|
@@except_classes ||= []
|
14
12
|
end
|
15
|
-
|
13
|
+
|
16
14
|
# Gets a list of the available models for this adapter
|
17
15
|
def self.model_classes
|
18
16
|
::Neo4j::Rails::Model.descendants.to_a.select{|k| !except_classes.include?(k.name)}
|
19
17
|
end
|
20
|
-
|
18
|
+
|
21
19
|
# get a list of column names for a given class
|
22
20
|
def column_names
|
23
21
|
klass._decl_props.keys
|
24
22
|
end
|
25
|
-
|
23
|
+
|
26
24
|
# Get an instance by id of the model
|
27
25
|
def get!(id)
|
28
|
-
|
26
|
+
klass.find!(wrap_key(id))
|
29
27
|
end
|
30
|
-
|
28
|
+
|
31
29
|
# Get an instance by id of the model
|
32
30
|
def get(id)
|
33
|
-
|
34
|
-
return nil if id.to_i == NEO4J_REF_NODE_ID # getting the ref_node in this way is not supported
|
35
|
-
klass.load(id)
|
31
|
+
klass.find(wrap_key(id))
|
36
32
|
end
|
37
|
-
|
33
|
+
|
38
34
|
# Find the first instance matching conditions
|
39
35
|
def find_first(conditions)
|
40
36
|
klass.first(conditions)
|
41
37
|
end
|
42
|
-
|
38
|
+
|
43
39
|
# Find all models matching conditions
|
44
40
|
def find_all(conditions)
|
45
41
|
klass.all(conditions)
|
46
42
|
end
|
47
|
-
|
43
|
+
|
48
44
|
# Create a model using attributes
|
49
45
|
def create!(attributes)
|
50
|
-
klass.create(attributes)
|
46
|
+
klass.create!(attributes)
|
51
47
|
end
|
52
48
|
end
|
53
49
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.4
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Andreas Ronge
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-10-
|
13
|
+
date: 2011-10-07 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -121,13 +121,13 @@ files:
|
|
121
121
|
- lib/neo4j/rels/traverser.rb
|
122
122
|
- lib/neo4j/rels/rels.rb
|
123
123
|
- lib/neo4j/rails/attributes.rb
|
124
|
+
- lib/neo4j/rails/rack_middleware.rb
|
124
125
|
- lib/neo4j/rails/model.rb
|
125
126
|
- lib/neo4j/rails/validations.rb
|
126
127
|
- lib/neo4j/rails/persistence.rb
|
127
128
|
- lib/neo4j/rails/serialization.rb
|
128
129
|
- lib/neo4j/rails/railtie.rb
|
129
130
|
- lib/neo4j/rails/rails.rb
|
130
|
-
- lib/neo4j/rails/lucene_connection_closer.rb
|
131
131
|
- lib/neo4j/rails/observer.rb
|
132
132
|
- lib/neo4j/rails/transaction.rb
|
133
133
|
- lib/neo4j/rails/timestamps.rb
|