neo4j 1.1.1-java → 1.1.2-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 -1
- data/config/neo4j/config.yml +4 -0
- data/lib/neo4j/config.rb +1 -0
- data/lib/neo4j/node_mixin/node_mixin.rb +1 -1
- data/lib/neo4j/rails/model.rb +20 -0
- data/lib/neo4j/rails/relationship.rb +12 -0
- data/lib/neo4j/rails/relationships/node_dsl.rb +55 -2
- data/lib/neo4j/rails/relationships/rels_dsl.rb +53 -1
- data/lib/neo4j/rels/rels.rb +25 -0
- data/lib/neo4j/rule/event_listener.rb +9 -5
- data/lib/neo4j/version.rb +1 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
== 1.1.
|
1
|
+
== 1.1.2 / 2011-06-08
|
2
|
+
* Added configuration option 'enable_rules' to disable the _all relationships and custom rules [#176]
|
3
|
+
* Added a #node method on the Neo4j::Node and Neo4j::NodeMixin. Works like the #rel method but returns the node instead. [#174]
|
4
|
+
* Simplify creating relationship between two existing nodes [#175]
|
5
|
+
|
6
|
+
== 1.1.1 / 2011-05-26
|
2
7
|
* Made neo4j compatible with rails 3.1.0.rc1 [#170]
|
3
8
|
* Fix for neo4j-devise [#171]
|
4
9
|
* BUG: Neo4j::GraphAlgo shortest path does raise exception if two nodes are not connected [#172]
|
data/config/neo4j/config.yml
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
# The folder location of the neo4j and lucene database
|
4
4
|
storage_path: db
|
5
5
|
|
6
|
+
# If enable neo4j.rb will create _all relationship to all instances inheriting from Neo4j::Rails::Model
|
7
|
+
# If disabled all custom rules will also be unavailable.
|
8
|
+
enable_rules: true
|
9
|
+
|
6
10
|
# When using the Neo4j::Model you can let neo4j automatically set timestamps when updating/creating nodes.
|
7
11
|
# If set to true neo4j.rb automatically timestamps create and update operations if the model has properties named created_at/created_on or updated_at/updated_on
|
8
12
|
# (similar to ActiveRecord).
|
data/lib/neo4j/config.rb
CHANGED
@@ -13,6 +13,7 @@ module Neo4j
|
|
13
13
|
# <tt>:storage_path</tt>:: default <tt>tmp/neo4j</tt> where the database is stored
|
14
14
|
# <tt>:timestamps</tt>:: default <tt>true</tt> for Rails Neo4j::Model - if timestamps should be used when saving the model
|
15
15
|
# <tt>:lucene</tt>:: default hash keys: <tt>:fulltext</tt>, <tt>:exact</tt> configuration how the lucene index is stored
|
16
|
+
# <tt>:enable_rules</tt>:: default true, if false the _all relationship to all instances will not be created and custom rules will not be available.
|
16
17
|
#
|
17
18
|
class Config
|
18
19
|
# This code is copied from merb-core/config.rb.
|
@@ -43,7 +43,7 @@ module Neo4j
|
|
43
43
|
|
44
44
|
include Neo4j::Rule::Functions
|
45
45
|
|
46
|
-
delegate :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :to_param, :getId,
|
46
|
+
delegate :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :node, :to_param, :getId,
|
47
47
|
:rel, :del, :list?, :print, :print_sub, :outgoing, :incoming, :both, :expand, :get_property, :set_property,
|
48
48
|
:equal?, :eql?, :==, :exist?, :getRelationships, :getSingleRelationship, :_rels, :rel, :wrapped_entity,
|
49
49
|
:to => :@_java_node, :allow_nil => true
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
+
|
4
|
+
# Includes the Neo4j::NodeMixin and adds ActiveRecord/Model like behaviour.
|
5
|
+
# That means for example that you don't have to care about transactions since they will be
|
6
|
+
# automatically be created when needed.
|
7
|
+
#
|
8
|
+
# ==== Traversals
|
9
|
+
# This class only expose a limited set of traversals.
|
10
|
+
# If you want to access the raw java node to do traversals use the _java_node.
|
11
|
+
#
|
12
|
+
# class Person < Neo4j::Rails::Model
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# person = Person.find(...)
|
16
|
+
# person._java_node.outgoing(:foo).depth(:all)...
|
17
|
+
#
|
18
|
+
# ==== has_n and has_one
|
19
|
+
#
|
20
|
+
# The has_n and has_one relationship accessors returns objects of type Neo4j::Rails::Relationships::RelsDSL
|
21
|
+
# and Neo4j::Rails::Relationships::NodesDSL which behaves more like the Active Record relationships.
|
22
|
+
#
|
3
23
|
class Model
|
4
24
|
include Neo4j::NodeMixin
|
5
25
|
|
@@ -1,8 +1,20 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
+
|
4
|
+
# Includes the Neo4j::RelationshipMixin and adds ActiveRecord/Model like behaviour.
|
5
|
+
# That means for example that you don't have to care about transactions since they will be
|
6
|
+
# automatically be created when needed.
|
7
|
+
#
|
8
|
+
# By default all relationships created by hte Neo4j::Rails::Model will be of this type unless it is specified by
|
9
|
+
# an has_n(...).relationship(relationship_class),
|
10
|
+
#
|
11
|
+
# Notice that this class works like any ActiveModel compliant object with callbacks and validations.
|
12
|
+
# It also implement timestamps (like active record), just add a updated_at or created_at attribute.
|
13
|
+
#
|
3
14
|
class Relationship
|
4
15
|
include Neo4j::RelationshipMixin
|
5
16
|
|
17
|
+
# The relationship type
|
6
18
|
attr_reader :type
|
7
19
|
|
8
20
|
index :_classname
|
@@ -2,7 +2,12 @@ module Neo4j
|
|
2
2
|
module Rails
|
3
3
|
module Relationships
|
4
4
|
|
5
|
-
class
|
5
|
+
# Instances of this class is returned from the #outgoing, #incoming and generated accessor methods:
|
6
|
+
# has_n and has_one.
|
7
|
+
# Notice that this class includes the Ruby Enumerable mixin.
|
8
|
+
# If you want to full traversal api use the wrapped java node instead (some_node._java_node.outgoing(...)).
|
9
|
+
#
|
10
|
+
class NodesDSL
|
6
11
|
include Enumerable
|
7
12
|
|
8
13
|
def initialize(storage, dir)
|
@@ -10,36 +15,56 @@ module Neo4j
|
|
10
15
|
@dir = dir
|
11
16
|
end
|
12
17
|
|
18
|
+
# Creates a new node given the specified attributes and connect it with a relationship.
|
19
|
+
# The new node and relationship will not be saved.
|
20
|
+
# Both the relationship class and the node class can be specified with the has_n and has_one.
|
21
|
+
#
|
22
|
+
# ==== Example
|
23
|
+
#
|
24
|
+
# class Person < Neo4j::Rails::Model
|
25
|
+
# has_n(:friends).to(Person).relationship(Friend)
|
26
|
+
# has_n(:knows)
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Person.friends.build(:name => 'kalle') # creates a Person and Friends class.
|
30
|
+
# Person.knows.build(:name => 'kalle') # creates a Neo4j::Rails::Model and Neo4j::Rails::Relationship class
|
31
|
+
#
|
13
32
|
def build(attrs)
|
14
33
|
self << (node = @storage.build(attrs))
|
15
34
|
node
|
16
35
|
end
|
17
36
|
|
37
|
+
# Same as #build except that the relationship and node are saved.
|
18
38
|
def create(attrs)
|
19
39
|
self << (node = @storage.create(attrs))
|
20
40
|
node.save
|
21
41
|
node
|
22
42
|
end
|
23
43
|
|
44
|
+
# Same as #create but will raise an exception if an error (like validation) occurs.
|
24
45
|
def create!(attrs)
|
25
46
|
self << (node = @storage.create(attrs))
|
26
47
|
node.save!
|
27
48
|
node
|
28
49
|
end
|
29
50
|
|
51
|
+
# Adds a new node to the relationship
|
30
52
|
def <<(other)
|
31
53
|
@storage.create_relationship_to(other, @dir)
|
32
54
|
self
|
33
55
|
end
|
34
56
|
|
57
|
+
# Specifies the depth of the traversal
|
35
58
|
def depth(d)
|
36
59
|
adapt_to_traverser.depth(d)
|
37
60
|
end
|
38
61
|
|
39
|
-
def adapt_to_traverser
|
62
|
+
def adapt_to_traverser # :nodoc:
|
40
63
|
Neo4j::Traversal::Traverser.new(@storage.node, @storage.rel_type, @dir)
|
41
64
|
end
|
42
65
|
|
66
|
+
# Returns the n:th item in the relationship.
|
67
|
+
# This method simply traverse all relationship and returns the n:th one.
|
43
68
|
def [](index)
|
44
69
|
i = 0
|
45
70
|
each{|x| return x if i == index; i += 1}
|
@@ -52,6 +77,29 @@ module Neo4j
|
|
52
77
|
super
|
53
78
|
end
|
54
79
|
|
80
|
+
# Find one node in the relationship.
|
81
|
+
#
|
82
|
+
# ==== Example
|
83
|
+
#
|
84
|
+
# class Actor < Neo4j::Rails::Model
|
85
|
+
# has_n(:acted_in)
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# # find all child nodes
|
89
|
+
# actor.acted_in.find(:all)
|
90
|
+
#
|
91
|
+
# # find first child node
|
92
|
+
# actor.acted_in.find(:first)
|
93
|
+
#
|
94
|
+
# # find a child node by node
|
95
|
+
# actor.acted_in.find(some_movie)
|
96
|
+
#
|
97
|
+
# # find a child node by id" do
|
98
|
+
# actor.acted_in.find(some_movie.id)
|
99
|
+
#
|
100
|
+
# #find a child node by delegate to Enumerable#find
|
101
|
+
# actor.acted_in.find{|n| n.title == 'movie_1'}
|
102
|
+
#
|
55
103
|
def find(*args, &block)
|
56
104
|
return super(*args, &block) if block
|
57
105
|
|
@@ -70,6 +118,8 @@ module Neo4j
|
|
70
118
|
end
|
71
119
|
end
|
72
120
|
|
121
|
+
# Same as #find except that it returns an Enumerator of all nodes found.
|
122
|
+
#
|
73
123
|
def all(*args)
|
74
124
|
unless args.empty?
|
75
125
|
enum = Enumerator.new(@storage, :each_node, @dir).find{|n| n == args.first}
|
@@ -78,6 +128,7 @@ module Neo4j
|
|
78
128
|
end
|
79
129
|
end
|
80
130
|
|
131
|
+
# Returns first node in the relationship specified by the arguments or returns nil.
|
81
132
|
def first(*args)
|
82
133
|
if result = all(*args)
|
83
134
|
if result.respond_to?(:collect) #if it's enumerable, get the first result
|
@@ -90,6 +141,8 @@ module Neo4j
|
|
90
141
|
end
|
91
142
|
end
|
92
143
|
|
144
|
+
# Destroys all nodes (!!!) and relationship in this relatationship.
|
145
|
+
# Notice, if you only want to destroy the relationship use the
|
93
146
|
def destroy_all
|
94
147
|
each {|n| n.destroy}
|
95
148
|
end
|
@@ -1,6 +1,21 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
3
|
module Relationships
|
4
|
+
|
5
|
+
# Instances of this class is returned from the #rels, and generated accessor methods:
|
6
|
+
# has_n and has_one.
|
7
|
+
# Notice, this class is very similar to the Neo4j::Rails::Relationships::NodesDSL except that
|
8
|
+
# if creates, finds relationships instead of nodes.
|
9
|
+
#
|
10
|
+
# ==== Example
|
11
|
+
# class Person < Neo4j::Rails::Model
|
12
|
+
# has_n(:friends)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# person = Person.find(...)
|
16
|
+
# person.friends_rels #=> returns a Neo4j::Rails::Relationships::RelsDSL
|
17
|
+
# rel = person.friends_rels.create(relationship properties)
|
18
|
+
#
|
4
19
|
class RelsDSL
|
5
20
|
include Enumerable
|
6
21
|
|
@@ -10,11 +25,15 @@ module Neo4j
|
|
10
25
|
end
|
11
26
|
|
12
27
|
|
28
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#build except that you specify the properties of the
|
29
|
+
# relationships and it returns a relationship
|
13
30
|
def build(attrs)
|
14
31
|
node = @storage.build(attrs)
|
15
32
|
@storage.create_relationship_to(node, @dir)
|
16
33
|
end
|
17
34
|
|
35
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#create except that you specify the properties of the
|
36
|
+
# relationships and it returns a relationship
|
18
37
|
def create(attrs)
|
19
38
|
node = @storage.create(attrs)
|
20
39
|
rel = @storage.create_relationship_to(node, @dir)
|
@@ -22,6 +41,18 @@ module Neo4j
|
|
22
41
|
rel
|
23
42
|
end
|
24
43
|
|
44
|
+
# Connects this node with an already existing other node with a new relationship.
|
45
|
+
# The relationship can optionally be given a hash of properties
|
46
|
+
# Does not save it.
|
47
|
+
# Returns the created relationship
|
48
|
+
def connect(other_node, relationship_properties = nil)
|
49
|
+
rel = @storage.create_relationship_to(other_node, @dir)
|
50
|
+
rel.attributes = relationship_properties if relationship_properties
|
51
|
+
rel
|
52
|
+
end
|
53
|
+
|
54
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#create! except that you specify the properties of the
|
55
|
+
# relationships and it returns a relationship
|
25
56
|
def create!(attrs)
|
26
57
|
node = @storage.create(attrs)
|
27
58
|
rel = @storage.create_relationship_to(node, @dir)
|
@@ -29,11 +60,21 @@ module Neo4j
|
|
29
60
|
rel
|
30
61
|
end
|
31
62
|
|
63
|
+
# Specifies that we want outgoing (undeclared) relationships.
|
64
|
+
#
|
65
|
+
# ==== Example
|
66
|
+
# class Thing < Neo4j::Rails::Model
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# t = Thing.find(...)
|
70
|
+
# t.rels(:reltype).outgoing # returns an enumerable of all outgoing relationship of type :reltype
|
71
|
+
#
|
32
72
|
def outgoing
|
33
73
|
@dir = :outgoing
|
34
74
|
self
|
35
75
|
end
|
36
76
|
|
77
|
+
# Returns incoming relationship See #outgoing
|
37
78
|
def incoming
|
38
79
|
@dir = :incoming
|
39
80
|
self
|
@@ -43,22 +84,28 @@ module Neo4j
|
|
43
84
|
@storage.each_rel(@dir, &block)
|
44
85
|
end
|
45
86
|
|
87
|
+
# Simply counts all relationships
|
46
88
|
def size
|
47
89
|
@storage.size(@dir)
|
48
90
|
end
|
49
91
|
|
92
|
+
# True if no relationship
|
50
93
|
def empty?
|
51
94
|
size == 0
|
52
95
|
end
|
53
96
|
|
97
|
+
# Destroys all relationships object. Will not destroy the nodes.
|
54
98
|
def destroy_all
|
55
99
|
each {|n| n.destroy}
|
56
100
|
end
|
57
101
|
|
102
|
+
# Delete all relationship.
|
58
103
|
def delete_all
|
59
104
|
each {|n| n.delete}
|
60
105
|
end
|
61
106
|
|
107
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#find except that it searches the relationships instead of
|
108
|
+
# the nodes.
|
62
109
|
def find(*args, &block)
|
63
110
|
return super(*args, &block) if block
|
64
111
|
|
@@ -77,6 +124,8 @@ module Neo4j
|
|
77
124
|
end
|
78
125
|
end
|
79
126
|
|
127
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#all except that it searches the relationships instead of
|
128
|
+
# the nodes.
|
80
129
|
def all(*args)
|
81
130
|
if args.first.class == Neo4j::Rails::Relationship #arg is a relationship
|
82
131
|
find_all{|r| r == args.first}
|
@@ -89,6 +138,8 @@ module Neo4j
|
|
89
138
|
end
|
90
139
|
end
|
91
140
|
|
141
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#first except that it searches the relationships instead of
|
142
|
+
# the nodes.
|
92
143
|
def first(*args)
|
93
144
|
if result = all(*args)
|
94
145
|
if result.respond_to?(:collect) #if it's enumerable, get the first result
|
@@ -101,7 +152,8 @@ module Neo4j
|
|
101
152
|
end
|
102
153
|
end
|
103
154
|
|
104
|
-
|
155
|
+
# Same as Neo4j::Rails::Relationships::NodesDSL#[] except that it returns the n:th relationship instead
|
156
|
+
# of the n:th node
|
105
157
|
def [](index)
|
106
158
|
i = 0
|
107
159
|
each{|x| return x if i == index; i += 1}
|
data/lib/neo4j/rels/rels.rb
CHANGED
@@ -7,6 +7,31 @@ module Neo4j
|
|
7
7
|
module Rels
|
8
8
|
include ToJava
|
9
9
|
|
10
|
+
# Returns the only node of a given type and direction that is attached to this node, or nil.
|
11
|
+
# This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or one relationships of a given type and direction to another node.
|
12
|
+
# Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships exist, it is a fatal error that should generate an exception.
|
13
|
+
|
14
|
+
# This method reflects that semantics and returns either:
|
15
|
+
# * nil if there are zero relationships of the given type and direction,
|
16
|
+
# * the relationship if there's exactly one, or
|
17
|
+
# * throws an unchecked exception in all other cases.
|
18
|
+
#
|
19
|
+
# This method should be used only in situations with an invariant as described above. In those situations, a "state-checking" method (e.g. #rel?) is not required,
|
20
|
+
# because this method behaves correctly "out of the box."
|
21
|
+
#
|
22
|
+
# Does return the Ruby wrapper object (if it has a '_classname' property) unlike the #_node version of this method
|
23
|
+
#
|
24
|
+
def node(dir, type)
|
25
|
+
n = _node(dir, type)
|
26
|
+
n && n.wrapper
|
27
|
+
end
|
28
|
+
|
29
|
+
# Same as #node but instead returns an unwrapped native java node instead
|
30
|
+
def _node(dir, type)
|
31
|
+
r = _rel(dir, type)
|
32
|
+
r && r._other_node(self._java_node)
|
33
|
+
end
|
34
|
+
|
10
35
|
# Returns an enumeration of relationship objects.
|
11
36
|
# It always returns relationship of depth one.
|
12
37
|
#
|
@@ -8,7 +8,7 @@ module Neo4j
|
|
8
8
|
|
9
9
|
def on_relationship_created(rel, *)
|
10
10
|
trigger_start_node = Rule.trigger?(rel._start_node)
|
11
|
-
trigger_end_node
|
11
|
+
trigger_end_node = Rule.trigger?(rel._end_node)
|
12
12
|
Rule.trigger_rules(rel._start_node) if trigger_start_node
|
13
13
|
Rule.trigger_rules(rel._end_node) if trigger_end_node
|
14
14
|
end
|
@@ -24,14 +24,14 @@ module Neo4j
|
|
24
24
|
return if del_rule_node
|
25
25
|
|
26
26
|
# do we have prop_aggregations for this
|
27
|
-
clazz
|
27
|
+
clazz = old_properties['_classname']
|
28
28
|
rule_node = Rule.rule_node_for(clazz)
|
29
29
|
return if rule_node.nil?
|
30
30
|
|
31
31
|
id = node.getId
|
32
32
|
rule_node.rules.each do |rule|
|
33
33
|
next if rule.functions.nil?
|
34
|
-
rule_name
|
34
|
+
rule_name = rule.rule_name.to_s
|
35
35
|
|
36
36
|
# is the rule node deleted ?
|
37
37
|
deleted_rule_node = data.deletedNodes.find { |n| n == rule_node.rule_node }
|
@@ -47,8 +47,12 @@ module Neo4j
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def on_neo4j_started(
|
51
|
-
|
50
|
+
def on_neo4j_started(db)
|
51
|
+
if Neo4j::Config[:enable_rules]
|
52
|
+
Rule.on_neo4j_started
|
53
|
+
else
|
54
|
+
db.event_handler.remove(self)
|
55
|
+
end
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
data/lib/neo4j/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.1.
|
5
|
+
version: 1.1.2
|
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-
|
13
|
+
date: 2011-06-08 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|