neo4j 1.2.3-java → 1.2.4-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|