neo4j 1.0.0.beta.21-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 +141 -0
- data/CONTRIBUTORS +17 -0
- data/Gemfile +16 -0
- data/README.rdoc +135 -0
- data/lib/generators/neo4j.rb +65 -0
- data/lib/generators/neo4j/model/model_generator.rb +39 -0
- data/lib/generators/neo4j/model/templates/model.erb +7 -0
- data/lib/neo4j.rb +77 -0
- data/lib/neo4j/config.rb +153 -0
- data/lib/neo4j/database.rb +56 -0
- data/lib/neo4j/equal.rb +21 -0
- data/lib/neo4j/event_handler.rb +116 -0
- data/lib/neo4j/index/class_methods.rb +62 -0
- data/lib/neo4j/index/index.rb +33 -0
- data/lib/neo4j/index/indexer.rb +312 -0
- data/lib/neo4j/index/indexer_registry.rb +68 -0
- data/lib/neo4j/index/lucene_query.rb +191 -0
- data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
- data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
- data/lib/neo4j/load.rb +21 -0
- data/lib/neo4j/mapping/class_methods/init_node.rb +50 -0
- data/lib/neo4j/mapping/class_methods/init_rel.rb +35 -0
- data/lib/neo4j/mapping/class_methods/list.rb +13 -0
- data/lib/neo4j/mapping/class_methods/property.rb +82 -0
- data/lib/neo4j/mapping/class_methods/relationship.rb +91 -0
- data/lib/neo4j/mapping/class_methods/rule.rb +295 -0
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +214 -0
- data/lib/neo4j/mapping/has_list.rb +134 -0
- data/lib/neo4j/mapping/has_n.rb +83 -0
- data/lib/neo4j/mapping/node_mixin.rb +112 -0
- data/lib/neo4j/mapping/relationship_mixin.rb +120 -0
- data/lib/neo4j/model.rb +4 -0
- data/lib/neo4j/neo4j.rb +95 -0
- data/lib/neo4j/node.rb +131 -0
- data/lib/neo4j/node_mixin.rb +4 -0
- data/lib/neo4j/node_relationship.rb +149 -0
- data/lib/neo4j/node_traverser.rb +157 -0
- data/lib/neo4j/property.rb +111 -0
- data/lib/neo4j/rails/attributes.rb +155 -0
- data/lib/neo4j/rails/callbacks.rb +34 -0
- data/lib/neo4j/rails/finders.rb +134 -0
- data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
- data/lib/neo4j/rails/mapping/property.rb +60 -0
- data/lib/neo4j/rails/model.rb +105 -0
- data/lib/neo4j/rails/persistence.rb +260 -0
- data/lib/neo4j/rails/railtie.rb +21 -0
- data/lib/neo4j/rails/relationships/mapper.rb +96 -0
- data/lib/neo4j/rails/relationships/relationship.rb +30 -0
- data/lib/neo4j/rails/relationships/relationships.rb +60 -0
- data/lib/neo4j/rails/serialization.rb +25 -0
- data/lib/neo4j/rails/timestamps.rb +65 -0
- data/lib/neo4j/rails/transaction.rb +67 -0
- data/lib/neo4j/rails/tx_methods.rb +15 -0
- data/lib/neo4j/rails/validations.rb +38 -0
- data/lib/neo4j/rails/validations/non_nil.rb +11 -0
- data/lib/neo4j/rails/validations/uniqueness.rb +37 -0
- data/lib/neo4j/relationship.rb +169 -0
- data/lib/neo4j/relationship_mixin.rb +4 -0
- data/lib/neo4j/relationship_traverser.rb +92 -0
- data/lib/neo4j/to_java.rb +31 -0
- data/lib/neo4j/transaction.rb +68 -0
- data/lib/neo4j/type_converters.rb +117 -0
- data/lib/neo4j/version.rb +3 -0
- data/lib/orm_adapter/adapters/neo4j.rb +55 -0
- data/lib/tmp/neo4j/active_tx_log +1 -0
- data/lib/tmp/neo4j/index/lucene-store.db +0 -0
- data/lib/tmp/neo4j/index/lucene.log.active +0 -0
- data/lib/tmp/neo4j/lucene-fulltext/lucene-store.db +0 -0
- data/lib/tmp/neo4j/lucene-fulltext/lucene.log.active +0 -0
- data/lib/tmp/neo4j/lucene/lucene-store.db +0 -0
- data/lib/tmp/neo4j/lucene/lucene.log.active +0 -0
- data/lib/tmp/neo4j/messages.log +85 -0
- data/lib/tmp/neo4j/neostore +0 -0
- data/lib/tmp/neo4j/neostore.id +0 -0
- data/lib/tmp/neo4j/neostore.nodestore.db +0 -0
- data/lib/tmp/neo4j/neostore.nodestore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.arrays +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.arrays.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.keys +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.keys.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.strings +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.strings.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshipstore.db +0 -0
- data/lib/tmp/neo4j/neostore.relationshipstore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names.id +0 -0
- data/lib/tmp/neo4j/nioneo_logical.log.active +0 -0
- data/lib/tmp/neo4j/tm_tx_log.1 +0 -0
- data/neo4j.gemspec +31 -0
- metadata +216 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
module Neo4j::Mapping
|
2
|
+
|
3
|
+
|
4
|
+
# A DSL for declared relationships has_n and has_one
|
5
|
+
# This DSL will be used to create accessor methods for relationships.
|
6
|
+
# Instead of using the 'raw' Neo4j::NodeMixin#rels method where one needs to know
|
7
|
+
# the name of relationship and direction one can use the generated accessor methods.
|
8
|
+
#
|
9
|
+
# The DSL can also be used to specify a mapping to a Ruby class for a relationship, see Neo4j::Relationships::DeclRelationshipDsl#relationship
|
10
|
+
#
|
11
|
+
# ==== Example
|
12
|
+
#
|
13
|
+
# class Folder
|
14
|
+
# include Neo4j::NodeMixin
|
15
|
+
# property :name
|
16
|
+
# # Declaring a Many relationship to any other node
|
17
|
+
# has_n(:files)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# class File
|
21
|
+
# include Neo4j::NodeMixin
|
22
|
+
# # declaring a incoming relationship from Folder's relationship files
|
23
|
+
# has_one(:folder).from(Folder, :files)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# The following methods will be generated:
|
27
|
+
# <b>Folder#files</b> :: returns an Enumerable of outgoing nodes for relationship 'files'
|
28
|
+
# <b>Folder#files_rels</b> :: returns an Enumerable of outgoing relationships for relationship 'files'
|
29
|
+
# <b>File#folder</b> :: for adding one node for the relationship 'files' from the outgoing Folder node
|
30
|
+
# <b>File#folder_rel</b> :: for accessing relationship 'files' from the outgoing Folder node
|
31
|
+
# <b>File#folder</b> :: for accessing nodes from relationship 'files' from the outgoing Folder node
|
32
|
+
#
|
33
|
+
class DeclRelationshipDsl
|
34
|
+
include Neo4j::ToJava
|
35
|
+
|
36
|
+
attr_reader :target_class, :direction, :rel_type
|
37
|
+
|
38
|
+
def initialize(method_id, has_one, target_class, params)
|
39
|
+
@direction = :outgoing
|
40
|
+
@method_id = method_id
|
41
|
+
@has_one = has_one
|
42
|
+
@rel_type = method_id
|
43
|
+
@target_class = target_class
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"DeclRelationshipDsl #{object_id} dir: #{@direction} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_one?
|
51
|
+
@has_one
|
52
|
+
end
|
53
|
+
|
54
|
+
def each_node(node, direction, &block) #:nodoc:
|
55
|
+
type = type_to_java(rel_type)
|
56
|
+
dir = dir_to_java(direction)
|
57
|
+
node._java_node.getRelationships(type, dir).each do |rel|
|
58
|
+
other = rel.getOtherNode(node).wrapper
|
59
|
+
block.call other
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def incoming? #:nodoc:
|
64
|
+
@direction == :incoming
|
65
|
+
end
|
66
|
+
|
67
|
+
def single_node(node) #:nodoc:
|
68
|
+
rel = single_relationship(node)
|
69
|
+
rel && rel.other_node(node).wrapper
|
70
|
+
end
|
71
|
+
|
72
|
+
def single_relationship(node) #:nodoc:
|
73
|
+
node._java_node.rel(direction, rel_type)
|
74
|
+
end
|
75
|
+
|
76
|
+
def _all_relationships(node) #:nodoc:
|
77
|
+
type = type_to_java(rel_type)
|
78
|
+
dir = dir_to_java(direction)
|
79
|
+
node._java_node.getRelationships(type, dir)
|
80
|
+
end
|
81
|
+
|
82
|
+
def all_relationships(node) #:nodoc:
|
83
|
+
Neo4j::RelationshipTraverser.new(node._java_node, [rel_type], direction)
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_relationship_to(node, other) # :nodoc:
|
87
|
+
from, to = incoming? ? [other, node] : [node, other]
|
88
|
+
java_type = type_to_java(rel_type)
|
89
|
+
|
90
|
+
rel = from._java_node.create_relationship_to(to._java_node, java_type)
|
91
|
+
rel[:_classname] = relationship_class.to_s if relationship_class
|
92
|
+
rel.wrapper
|
93
|
+
end
|
94
|
+
|
95
|
+
# Specifies an outgoing relationship.
|
96
|
+
# The name of the outgoing class will be used as a prefix for the relationship used.
|
97
|
+
#
|
98
|
+
# ==== Arguments
|
99
|
+
# clazz:: to which class this relationship goes
|
100
|
+
# relationship:: optional, the relationship to use
|
101
|
+
#
|
102
|
+
# ==== Example
|
103
|
+
# class FolderNode
|
104
|
+
# include Neo4j::NodeMixin
|
105
|
+
# has_n(:files).to(FileNode)
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# folder = FolderNode.new
|
109
|
+
# # generate a relationship between folder and file of type 'FileNode#files'
|
110
|
+
# folder.files << FileNode.new
|
111
|
+
#
|
112
|
+
def to(*args)
|
113
|
+
@direction = :outgoing
|
114
|
+
|
115
|
+
if (args.size > 1)
|
116
|
+
raise "only one argument expected - the class of the node this relationship points to, got #{args.inspect}"
|
117
|
+
elsif (Class === args[0])
|
118
|
+
# handle e.g. has_n(:friends).to(class)
|
119
|
+
@target_class = args[0]
|
120
|
+
@rel_type = "#{@target_class}##{@method_id}"
|
121
|
+
else
|
122
|
+
raise "Expected a class for, got #{args[0]}"
|
123
|
+
end
|
124
|
+
self
|
125
|
+
end
|
126
|
+
|
127
|
+
# Specifies an incoming relationship.
|
128
|
+
# Will use the outgoing relationship given by the from class.
|
129
|
+
#
|
130
|
+
# ==== Example, with prefix FileNode
|
131
|
+
# class FolderNode
|
132
|
+
# include Neo4j::NodeMixin
|
133
|
+
# has_n(:files).to(FileNode)
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
# class FileNode
|
137
|
+
# include Neo4j::NodeMixin
|
138
|
+
# # will only traverse any incoming relationship of type files from node FileNode
|
139
|
+
# has_one(:folder).from(FileNode, :files)
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# file = FileNode.new
|
143
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
|
144
|
+
# file.folder = FolderNode.new
|
145
|
+
#
|
146
|
+
# ==== Example, without prefix
|
147
|
+
#
|
148
|
+
# class FolderNode
|
149
|
+
# include Neo4j::NodeMixin
|
150
|
+
# has_n(:files)
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# class FileNode
|
154
|
+
# include Neo4j::NodeMixin
|
155
|
+
# has_one(:folder).from(:files) # will traverse any incoming relationship of type files
|
156
|
+
# end
|
157
|
+
#
|
158
|
+
# file = FileNode.new
|
159
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file
|
160
|
+
# file.folder = FolderNode.new
|
161
|
+
#
|
162
|
+
#
|
163
|
+
def from(*args)
|
164
|
+
@direction = :incoming
|
165
|
+
|
166
|
+
if (args.size > 1)
|
167
|
+
# handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
|
168
|
+
@rel_type = "#{@target_class}##{args[1]}"
|
169
|
+
@target_class = args[0]
|
170
|
+
other_class_dsl = @target_class._decl_rels[args[1]]
|
171
|
+
if other_class_dsl
|
172
|
+
@relationship = other_class_dsl.relationship_class
|
173
|
+
else
|
174
|
+
puts "WARNING: Unknown outgoing relationship #{args[1]} on #{@target_class}"
|
175
|
+
end
|
176
|
+
elsif (Symbol === args[0])
|
177
|
+
# handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
|
178
|
+
@rel_type = args[0]
|
179
|
+
else
|
180
|
+
raise "Expected a symbol for, got #{args[0]}"
|
181
|
+
end
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
185
|
+
# Specifies which relationship ruby class to use for the relationship
|
186
|
+
#
|
187
|
+
# ==== Example
|
188
|
+
#
|
189
|
+
# class OrderLine
|
190
|
+
# include Neo4j::RelationshipMixin
|
191
|
+
# property :units
|
192
|
+
# property :unit_price
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# class Order
|
196
|
+
# property :total_cost
|
197
|
+
# property :dispatched
|
198
|
+
# has_n(:products).to(Product).relationship(OrderLine)
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# order = Order.new
|
202
|
+
# order.products << Product.new
|
203
|
+
# order.products_rels.first # => OrderLine
|
204
|
+
#
|
205
|
+
def relationship(rel_class)
|
206
|
+
@relationship = rel_class
|
207
|
+
self
|
208
|
+
end
|
209
|
+
|
210
|
+
def relationship_class # :nodoc:
|
211
|
+
@relationship
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Mapping
|
3
|
+
|
4
|
+
# Enables creating and traversal of nodes in a list.
|
5
|
+
#
|
6
|
+
# It uses the TimeLine http://api.neo4j.org/current/org/neo4j/index/timeline/Timeline.html,
|
7
|
+
#
|
8
|
+
# Includes the Enumerable Mixin.
|
9
|
+
# The Neo4j::Mapping::ClassMethods::List#has_list methods returns an object of this type.
|
10
|
+
#
|
11
|
+
# === Example, index same as size of list
|
12
|
+
#
|
13
|
+
# class Person
|
14
|
+
# include Neo4j::NodeMixin
|
15
|
+
# has_list :feeds
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# person = Person.new
|
19
|
+
# person.feeds << Neo4j::Node:new << Neo4j::Node.new
|
20
|
+
#
|
21
|
+
# === Example, using a custom index
|
22
|
+
#
|
23
|
+
# class Person
|
24
|
+
# include Neo4j::NodeMixin
|
25
|
+
# has_list :feeds
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# person = Person.new
|
29
|
+
# person.feeds[42] = (a = Neo4j::Node:new)
|
30
|
+
# person.feeds[1251] = Neo4j::Node.new
|
31
|
+
#
|
32
|
+
# person.feeds[42] # => a
|
33
|
+
#
|
34
|
+
class HasList
|
35
|
+
include Enumerable
|
36
|
+
include ToJava
|
37
|
+
|
38
|
+
def initialize(node, name)
|
39
|
+
@time_line = org.neo4j.index.timeline.Timeline.new(name, node._java_node, true, Neo4j.started_db.graph)
|
40
|
+
@node = node
|
41
|
+
@name = name
|
42
|
+
self.size = 0 unless size
|
43
|
+
end
|
44
|
+
|
45
|
+
# returns the size of this list
|
46
|
+
# notice in order to get correct result you must call the #remove method when an item is removed from the list
|
47
|
+
def size
|
48
|
+
@node["_list_size_#{@name}"]
|
49
|
+
end
|
50
|
+
|
51
|
+
# same as #size == 0
|
52
|
+
def empty?
|
53
|
+
size == 0
|
54
|
+
end
|
55
|
+
|
56
|
+
# returns the first node with index n
|
57
|
+
def [](n)
|
58
|
+
@time_line.getAllNodesBetween(n-1, n+1).first
|
59
|
+
end
|
60
|
+
|
61
|
+
# returns all nodes with the given index n
|
62
|
+
def all(n)
|
63
|
+
@time_line.getAllNodesBetween(n-1, n+1)
|
64
|
+
end
|
65
|
+
|
66
|
+
# returns the first node in the list or nil
|
67
|
+
def first
|
68
|
+
@time_line.first_node
|
69
|
+
end
|
70
|
+
|
71
|
+
# returns the last node in the list or nil
|
72
|
+
def last
|
73
|
+
@time_line.last_node
|
74
|
+
end
|
75
|
+
|
76
|
+
# adds a node to the list with the given index n
|
77
|
+
def []=(n, other_node)
|
78
|
+
@time_line.add_node(other_node, n)
|
79
|
+
self.size = self.size + 1
|
80
|
+
end
|
81
|
+
|
82
|
+
# returns all the nodes between the given Range
|
83
|
+
def between(range)
|
84
|
+
@time_line.getAllNodesBetween(range.first-1, range.end+1)
|
85
|
+
end
|
86
|
+
|
87
|
+
# removes one node from the list and decrases the size of the list,
|
88
|
+
def remove(node)
|
89
|
+
@time_line.remove_node(node)
|
90
|
+
self.size = self.size - 1
|
91
|
+
end
|
92
|
+
|
93
|
+
# Required by the Enumerable mixin so that we can
|
94
|
+
#
|
95
|
+
# ==== Example
|
96
|
+
#
|
97
|
+
# class Person
|
98
|
+
# include Neo4j::NodeMixin
|
99
|
+
# has_list :feeds
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# person.feeds.each {|node| node}
|
103
|
+
#
|
104
|
+
def each
|
105
|
+
@time_line.all_nodes.iterator.each { |node|
|
106
|
+
if @raw then
|
107
|
+
yield node
|
108
|
+
else
|
109
|
+
yield node.wrapper
|
110
|
+
end }
|
111
|
+
end
|
112
|
+
|
113
|
+
# If called then it will only return the raw java nodes and not the Ruby wrappers using the Neo4j::NodeMixin
|
114
|
+
def raw
|
115
|
+
@raw = true
|
116
|
+
end
|
117
|
+
|
118
|
+
def <<(other)
|
119
|
+
@time_line.add_node(other, size)
|
120
|
+
self.size = self.size + 1
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
private
|
126
|
+
def size=(size)
|
127
|
+
@node["_list_size_#{@name}"] = size
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Mapping
|
3
|
+
|
4
|
+
# Enables creating and traversal of nodes.
|
5
|
+
#
|
6
|
+
# Includes the Enumerable Mixin.
|
7
|
+
# The Neo4j::Mapping::ClassMethods::Relationship#has_n and Neo4j::Mapping::ClassMethods::Relationship#one
|
8
|
+
# methods returns an object of this type.
|
9
|
+
#
|
10
|
+
# ==== See Also
|
11
|
+
# Neo4j::Mapping::ClassMethods::Relationship
|
12
|
+
#
|
13
|
+
class HasN
|
14
|
+
include Enumerable
|
15
|
+
include ToJava
|
16
|
+
|
17
|
+
def initialize(node, dsl) # :nodoc:
|
18
|
+
@node = node
|
19
|
+
@direction = dsl.direction
|
20
|
+
@dsl = dsl
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
"HasN [#@direction, id: #{@node.neo_id} type: #{@dsl && @dsl.rel_type} dsl:#{@dsl}]"
|
25
|
+
end
|
26
|
+
|
27
|
+
def size
|
28
|
+
[*self].size
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :length, :size
|
32
|
+
|
33
|
+
def [](index)
|
34
|
+
each_with_index {|node,i| break node if index == i}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Pretend we are an array - this is neccessarly for Rails actionpack/actionview/formhelper to work with this
|
38
|
+
def is_a?(type)
|
39
|
+
# ActionView requires this for nested attributes to work
|
40
|
+
return true if Array == type
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
# Required by the Enumerable mixin.
|
45
|
+
def each(&block)
|
46
|
+
@dsl.each_node(@node, @direction, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Returns true if there are no node in this type of relationship
|
51
|
+
def empty?
|
52
|
+
first == nil
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Creates a relationship instance between this and the other node.
|
57
|
+
# Returns the relationship object
|
58
|
+
def new(other)
|
59
|
+
@dsl.create_relationship_to(@node, other)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Creates a relationship between this and the other node.
|
64
|
+
#
|
65
|
+
# ==== Example
|
66
|
+
#
|
67
|
+
# n1 = Node.new # Node has declared having a friend type of relationship
|
68
|
+
# n2 = Node.new
|
69
|
+
# n3 = Node.new
|
70
|
+
#
|
71
|
+
# n1 << n2 << n3
|
72
|
+
#
|
73
|
+
# ==== Returns
|
74
|
+
# self
|
75
|
+
#
|
76
|
+
def <<(other)
|
77
|
+
@dsl.create_relationship_to(@node, other)
|
78
|
+
self
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "active_support/core_ext/module/delegation"
|
2
|
+
|
3
|
+
module Neo4j::Mapping
|
4
|
+
|
5
|
+
# This Mixin is used to wrap Neo4j Java Nodes in Ruby objects.
|
6
|
+
#
|
7
|
+
# It includes a number of mixins and forwards some methods to the raw Java node which in term includes a number of mixins, see below.
|
8
|
+
#
|
9
|
+
# === Instance Methods
|
10
|
+
#
|
11
|
+
# Mixins:
|
12
|
+
# * Neo4j::Index
|
13
|
+
# * Neo4j::Property
|
14
|
+
# * Neo4j::NodeRelationship
|
15
|
+
# * Neo4j::Equal
|
16
|
+
# * Neo4j::Index
|
17
|
+
#
|
18
|
+
# === Class Methods
|
19
|
+
#
|
20
|
+
# Mixins:
|
21
|
+
# * Neo4j::Mapping::ClassMethods::Root
|
22
|
+
# * Neo4j::Mapping::ClassMethods::Property
|
23
|
+
# * Neo4j::Mapping::ClassMethods::InitNode
|
24
|
+
# * Neo4j::Mapping::ClassMethods::Relationship
|
25
|
+
# * Neo4j::Mapping::ClassMethods::Rule
|
26
|
+
# * Neo4j::Mapping::ClassMethods::List
|
27
|
+
# * Neo4j::Index::ClassMethods
|
28
|
+
#
|
29
|
+
module NodeMixin
|
30
|
+
include Neo4j::Index
|
31
|
+
|
32
|
+
delegate :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :to_param, :getId,
|
33
|
+
:rel, :del, :list?, :print, :print_sub, :outgoing, :incoming, :both,
|
34
|
+
:equal?, :eql?, :==, :exist?, :getRelationships, :getSingleRelationship, :_rels, :rel,
|
35
|
+
:to => :@_java_node, :allow_nil => true
|
36
|
+
|
37
|
+
|
38
|
+
# --------------------------------------------------------------------------
|
39
|
+
# Initialization methods
|
40
|
+
#
|
41
|
+
|
42
|
+
|
43
|
+
# Init this node with the specified java neo node
|
44
|
+
#
|
45
|
+
def init_on_load(java_node) # :nodoc:
|
46
|
+
@_java_node = java_node
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Creates a new node and initialize with given properties.
|
51
|
+
# You can override this to provide your own initialization.
|
52
|
+
#
|
53
|
+
def init_on_create(*args) # :nodoc:
|
54
|
+
self[:_classname] = self.class.to_s
|
55
|
+
if args[0].respond_to?(:each_pair)
|
56
|
+
args[0].each_pair { |k, v| respond_to?("#{k}=")? self.send("#{k}=", v) : @_java_node[k] = v }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the org.neo4j.graphdb.Node wrapped object
|
61
|
+
def _java_node
|
62
|
+
@_java_node
|
63
|
+
end
|
64
|
+
|
65
|
+
def trigger_rules
|
66
|
+
self.class.trigger_rules(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def _decl_rels_for(rel_type)
|
71
|
+
self.class._decl_rels[rel_type]
|
72
|
+
end
|
73
|
+
|
74
|
+
def wrapper
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def self.included(c) # :nodoc:
|
80
|
+
c.instance_eval do
|
81
|
+
class << self
|
82
|
+
alias_method :orig_new, :new
|
83
|
+
end
|
84
|
+
end unless c.respond_to?(:orig_new)
|
85
|
+
|
86
|
+
c.class_inheritable_hash :_decl_props
|
87
|
+
c._decl_props ||= {}
|
88
|
+
|
89
|
+
c.class_inheritable_hash :_decl_rels
|
90
|
+
c._decl_rels ||= {}
|
91
|
+
|
92
|
+
c.extend ClassMethods::Property
|
93
|
+
c.extend ClassMethods::InitNode
|
94
|
+
c.extend ClassMethods::Relationship
|
95
|
+
c.extend ClassMethods::Rule
|
96
|
+
c.extend ClassMethods::List
|
97
|
+
c.extend Neo4j::Index::ClassMethods
|
98
|
+
|
99
|
+
def c.inherited(subclass)
|
100
|
+
# inherit the index properties
|
101
|
+
subclass.node_indexer self
|
102
|
+
|
103
|
+
# inherit the rules too
|
104
|
+
subclass.inherit_rules_from self
|
105
|
+
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
c.node_indexer c
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|