neo4j 3.0.0.alpha.8 → 3.0.0.alpha.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,252 +0,0 @@
1
- module Neo4j
2
- module ActiveNode
3
- module HasN
4
-
5
-
6
- # A DSL for declared relationships has_n and has_one
7
- # This DSL will be used to create accessor methods for relationships.
8
- # Instead of using the 'raw' Neo4j::ActiveNode#rels method where one needs to know
9
- # the name of relationship and direction one can use the generated accessor methods.
10
- #
11
- # @example
12
- #
13
- # class Folder
14
- # include Neo4j::ActiveNode
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::ActiveNode
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 DeclRel
34
- attr_reader :source_class, :dir, :rel_type, :method_id
35
-
36
- def initialize(method_id, has_one, source_class, *callbacks)
37
- @method_id = method_id
38
- @has_one = has_one
39
- @dir = :outgoing
40
- @rel_type = method_id.to_sym
41
- @source_class = source_class
42
- unless callbacks.empty?
43
- @before_callback = callbacks.first[:before] || nil
44
- @after_callback = callbacks.first[:after] || nil
45
- end
46
- end
47
-
48
- def inherit_new
49
- base = self
50
- dr = DeclRel.new(@method_id, @has_one, @source_class)
51
- dr.instance_eval do
52
- @dir = base.dir
53
- @rel_type = base.rel_type
54
- @target_name = base.target_name if base.target_name
55
- @source_class = base.source_class
56
- end
57
- dr
58
- end
59
-
60
- def to_s
61
- "DeclRel one #{has_one?}, dir: #{@dir}, rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_name}"
62
- end
63
-
64
- def inspect
65
- to_s
66
- end
67
-
68
- # @return [true, false]
69
- def has_one?
70
- @has_one
71
- end
72
-
73
- # @return [true, false]
74
- def has_n?
75
- !@has_one
76
- end
77
-
78
- # @return [true,false]
79
- def incoming? #:nodoc:
80
- @dir == :incoming
81
- end
82
-
83
-
84
- # Declares an outgoing relationship type.
85
- # It is possible to prefix relationship types so that it's possible to distinguish different incoming relationships.
86
- # There is no validation that the added node is of the specified class.
87
- #
88
- # @example Example
89
- # class FolderNode
90
- # include Neo4j::ActiveNode
91
- # has_n(:files).to(FileNode)
92
- # has_one(:root).to("FileSystem") # also possible, if the class is not defined yet
93
- # end
94
- #
95
- # folder = FolderNode.new
96
- # # generate a relationship between folder and file of type 'FileNode#files'
97
- # folder.files << FileNode.new
98
- #
99
- # @example relationship with a hash, user defined relationship
100
- #
101
- # class FolderNode
102
- # include Neo4j::ActiveNode
103
- # has_n(:files).to('FolderNode#files')
104
- # end
105
- #
106
- # @example without prefix
107
- #
108
- # class FolderNode
109
- # include Neo4j::ActiveNode
110
- # has_n(:files).to(:contains)
111
- # end
112
- #
113
- # file = FileNode.new
114
- # # create an outgoing relationship of type 'contains' from folder node to file
115
- # folder.files << FolderNode.new
116
- #
117
- # @param [Class, String, Symbol] target the other class to which this relationship goes (if String or Class) or the relationship (if Symbol)
118
- # @param [String, Symbol] rel_type the rel_type postfix for the relationships, which defaults to the same as the has_n/one method id
119
- # @return self
120
- def to(target, rel_type = @method_id)
121
- @dir = :outgoing
122
-
123
- case target
124
- when /#/
125
- @target_name, _ = target.to_s.split("#")
126
- @rel_type = target.to_sym
127
- when Class, String
128
- @target_name = target.to_s
129
- @rel_type = "#{@source_class}##{rel_type}".to_sym
130
- when Symbol
131
- @target_name = nil
132
- @rel_type = target.to_sym
133
- else
134
- raise "Expected a class or a symbol for, got #{target}/#{target.class}"
135
- end
136
- self
137
- end
138
-
139
- # Specifies an incoming relationship.
140
- # Will use the outgoing relationship given by the from class.
141
- #
142
- # @example with prefix FileNode
143
- # class FolderNode
144
- # include Neo4j::NodeMixin
145
- # has_n(:files).to(FileNode)
146
- # end
147
- #
148
- # class FileNode
149
- # include Neo4j::NodeMixin
150
- # # will only traverse any incoming relationship of type files from node FileNode
151
- # has_one(:folder).from(FolderNode.files)
152
- # # alternative: has_one(:folder).from(FolderNode, :files)
153
- # end
154
- #
155
- # file = FileNode.new
156
- # # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
157
- # file.folder = FolderNode.new
158
- #
159
- # @example without prefix
160
- #
161
- # class FolderNode
162
- # include Neo4j::NodeMixin
163
- # has_n(:files)
164
- # end
165
- #
166
- # class FileNode
167
- # include Neo4j::NodeMixin
168
- # has_one(:folder).from(:files) # will traverse any incoming relationship of type files
169
- # end
170
- #
171
- # file = FileNode.new
172
- # # create an outgoing relationship of type 'files' from folder node to file
173
- # file.folder = FolderNode.new
174
- #
175
- #
176
- def from(target, rel_type=@method_id)
177
- @dir = :incoming
178
-
179
- case target
180
- when /#/
181
- @target_name, _ = target.to_s.split("#")
182
- @rel_type = target
183
- when Class, String
184
- @target_name = target.to_s
185
- @rel_type = "#{@target_name}##{rel_type}".to_sym
186
- when Symbol
187
- @target_name = nil
188
- @rel_type = target.to_sym
189
- else
190
- raise "Expected a class or a symbol for, got #{target}/#{target.class}"
191
- end
192
- self
193
- end
194
-
195
-
196
- # @private
197
- def target_name
198
- @target_name
199
- end
200
-
201
- def target_class
202
- @target_name && @target_name.split("::").inject(Kernel) { |container, name| container.const_get(name.to_s) }
203
- end
204
-
205
-
206
- # @private
207
- def each_node(node, &block)
208
- node.nodes(dir: dir, type: rel_type).each { |n| block.call(n) }
209
- end
210
-
211
- def all_relationships(node)
212
- to_enum(:each_rel, node)
213
- end
214
-
215
- def each_rel(node, &block) #:nodoc:
216
- node.rels(dir: dir, type: rel_type).each { |rel| block.call(rel) }
217
- end
218
-
219
- def single_relationship(node)
220
- node.rel(dir: dir, type: rel_type)
221
- end
222
-
223
- def single_node(node)
224
- node.node(dir: dir, type: rel_type)
225
- end
226
-
227
- # @private
228
- def create_relationship_to(node, other, relationship_props={}) # :nodoc:
229
- from, to = incoming? ? [other, node] : [node, other]
230
- before_callback_result = do_before_callback(node, from, to)
231
- return false if before_callback_result == false
232
-
233
- result = from.create_rel(@rel_type, to, relationship_props)
234
-
235
- after_callback_result = do_after_callback(node, from, to)
236
- after_callback_result == false ? false : result
237
- end
238
-
239
- private
240
-
241
- def do_before_callback(caller, from, to)
242
- @before_callback ? caller.send(@before_callback, from, to) : true
243
- end
244
-
245
- def do_after_callback(caller, from, to)
246
- @after_callback ? caller.send(@after_callback, from, to) : true
247
- end
248
-
249
- end
250
- end
251
- end
252
- end