neo4j 1.0.0.beta.20 → 3.0.0.alpha.2

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.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +243 -0
  3. data/CONTRIBUTORS +12 -0
  4. data/Gemfile +10 -11
  5. data/README.md +23 -0
  6. data/bin/neo4j-jars +33 -0
  7. data/config/locales/en.yml +5 -0
  8. data/config/neo4j/config.yml +98 -0
  9. data/lib/neo4j.rb +28 -68
  10. data/lib/neo4j/active_node.rb +60 -0
  11. data/lib/neo4j/active_node/callbacks.rb +41 -0
  12. data/lib/neo4j/active_node/has_n.rb +138 -0
  13. data/lib/neo4j/active_node/has_n/decl_rel.rb +236 -0
  14. data/lib/neo4j/active_node/has_n/nodes.rb +82 -0
  15. data/lib/neo4j/active_node/identity.rb +28 -0
  16. data/lib/neo4j/active_node/initialize.rb +24 -0
  17. data/lib/neo4j/active_node/labels.rb +142 -0
  18. data/lib/neo4j/active_node/persistence.rb +193 -0
  19. data/lib/neo4j/active_node/property.rb +41 -0
  20. data/lib/neo4j/active_node/rels.rb +11 -0
  21. data/lib/neo4j/active_node/validations.rb +51 -0
  22. data/lib/neo4j/railtie.rb +40 -0
  23. data/lib/neo4j/version.rb +1 -1
  24. data/lib/neo4j/wrapper.rb +25 -0
  25. data/neo4j.gemspec +25 -15
  26. metadata +136 -149
  27. data/README.rdoc +0 -135
  28. data/lib/generators/neo4j.rb +0 -65
  29. data/lib/generators/neo4j/model/model_generator.rb +0 -39
  30. data/lib/generators/neo4j/model/templates/model.erb +0 -7
  31. data/lib/neo4j/config.rb +0 -153
  32. data/lib/neo4j/database.rb +0 -56
  33. data/lib/neo4j/equal.rb +0 -21
  34. data/lib/neo4j/event_handler.rb +0 -116
  35. data/lib/neo4j/index/class_methods.rb +0 -62
  36. data/lib/neo4j/index/index.rb +0 -33
  37. data/lib/neo4j/index/indexer.rb +0 -312
  38. data/lib/neo4j/index/indexer_registry.rb +0 -68
  39. data/lib/neo4j/index/lucene_query.rb +0 -191
  40. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  41. data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
  42. data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
  43. data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
  44. data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
  45. data/lib/neo4j/load.rb +0 -21
  46. data/lib/neo4j/mapping/class_methods/init_node.rb +0 -50
  47. data/lib/neo4j/mapping/class_methods/init_rel.rb +0 -35
  48. data/lib/neo4j/mapping/class_methods/property.rb +0 -80
  49. data/lib/neo4j/mapping/class_methods/relationship.rb +0 -90
  50. data/lib/neo4j/mapping/class_methods/root.rb +0 -31
  51. data/lib/neo4j/mapping/class_methods/rule.rb +0 -295
  52. data/lib/neo4j/mapping/decl_relationship_dsl.rb +0 -214
  53. data/lib/neo4j/mapping/has_n.rb +0 -83
  54. data/lib/neo4j/mapping/node_mixin.rb +0 -97
  55. data/lib/neo4j/mapping/relationship_mixin.rb +0 -117
  56. data/lib/neo4j/model.rb +0 -4
  57. data/lib/neo4j/neo4j.rb +0 -95
  58. data/lib/neo4j/node.rb +0 -131
  59. data/lib/neo4j/node_mixin.rb +0 -4
  60. data/lib/neo4j/node_relationship.rb +0 -149
  61. data/lib/neo4j/node_traverser.rb +0 -157
  62. data/lib/neo4j/property.rb +0 -111
  63. data/lib/neo4j/rails/finders.rb +0 -121
  64. data/lib/neo4j/rails/lucene_connection_closer.rb +0 -19
  65. data/lib/neo4j/rails/mapping/property.rb +0 -35
  66. data/lib/neo4j/rails/model.rb +0 -324
  67. data/lib/neo4j/rails/railtie.rb +0 -16
  68. data/lib/neo4j/rails/transaction.rb +0 -67
  69. data/lib/neo4j/rails/tx_methods.rb +0 -15
  70. data/lib/neo4j/rails/validations/non_nil.rb +0 -11
  71. data/lib/neo4j/rails/validations/uniqueness.rb +0 -31
  72. data/lib/neo4j/rails/value.rb +0 -124
  73. data/lib/neo4j/rails/value_properties.rb +0 -29
  74. data/lib/neo4j/relationship.rb +0 -169
  75. data/lib/neo4j/relationship_mixin.rb +0 -4
  76. data/lib/neo4j/relationship_traverser.rb +0 -92
  77. data/lib/neo4j/to_java.rb +0 -31
  78. data/lib/neo4j/transaction.rb +0 -68
  79. data/lib/neo4j/type_converters.rb +0 -98
data/lib/neo4j.rb CHANGED
@@ -1,70 +1,30 @@
1
- include Java
2
-
3
- require 'enumerator'
4
- require 'forwardable'
5
- require 'time'
6
- require 'date'
7
-
8
- require 'neo4j/jars/neo4j-index-1.2-1.2.M03.jar'
9
- require 'neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar'
10
- require 'neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar'
11
- require 'neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar'
12
- require 'neo4j/jars/lucene-core-3.0.2.jar'
13
- require 'neo4j/to_java'
14
1
  require 'neo4j/version'
15
- require 'neo4j/equal'
16
-
17
- require 'neo4j/event_handler'
18
- require 'neo4j/database'
19
- require 'neo4j/neo4j'
20
-
21
- require 'neo4j/index/index'
22
- require 'neo4j/index/class_methods'
23
- require 'neo4j/index/indexer_registry'
24
- require 'neo4j/index/indexer'
25
- require 'neo4j/index/lucene_query'
26
- require 'neo4j/relationship_traverser'
27
- require 'neo4j/node_traverser'
28
- require 'neo4j/property'
29
- require 'neo4j/transaction'
30
- require 'neo4j/node_relationship'
31
- require 'neo4j/load'
32
- require 'neo4j/relationship'
33
- require 'neo4j/node'
34
- require 'neo4j/config'
35
- require 'neo4j/type_converters'
36
- require 'neo4j/mapping/class_methods/init_node'
37
- require 'neo4j/mapping/class_methods/init_rel'
38
- require 'neo4j/mapping/class_methods/root'
39
- require 'neo4j/mapping/class_methods/property'
40
- require 'neo4j/mapping/class_methods/relationship'
41
- require 'neo4j/mapping/decl_relationship_dsl'
42
- require 'neo4j/mapping/has_n'
43
- require 'neo4j/mapping/node_mixin'
44
- require 'neo4j/mapping/relationship_mixin'
45
- require 'neo4j/node_mixin'
46
- require 'neo4j/relationship_mixin'
47
- require 'neo4j/mapping/class_methods/rule'
48
-
49
- # rails
50
- require 'rails/railtie'
51
- require 'active_model'
52
- require 'neo4j/rails/tx_methods'
53
- require 'neo4j/rails/transaction'
54
- require 'neo4j/rails/railtie'
55
- require 'neo4j/rails/validations/uniqueness'
56
- require 'neo4j/rails/validations/non_nil'
57
- require 'neo4j/rails/finders'
58
- require 'neo4j/rails/mapping/property'
59
- require 'neo4j/rails/model'
60
- require 'neo4j/rails/value_properties'
61
- require 'neo4j/rails/value'
62
- require 'neo4j/rails/lucene_connection_closer'
63
-
64
- require 'neo4j/model'
65
-
66
-
67
-
68
- # hmm, looks like Enumerator have been moved in some ruby versions
69
- Enumerator = Enumerable::Enumerator unless defined? Enumerator
70
2
 
3
+ #require "delegate"
4
+ #require "time"
5
+ #require "set"
6
+ #
7
+ #require "active_support/core_ext"
8
+ #require "active_support/json"
9
+ #require "active_support/inflector"
10
+ #require "active_support/time_with_zone"
11
+
12
+ require "neo4j-core"
13
+ require "active_model"
14
+ require 'active_support/concern'
15
+ require 'active_support/core_ext/class/attribute.rb'
16
+
17
+ require 'active_attr'
18
+ require 'neo4j/wrapper'
19
+ require "neo4j/active_node/labels"
20
+ require 'neo4j/active_node/identity'
21
+ require 'neo4j/active_node/callbacks'
22
+ require 'neo4j/active_node/initialize'
23
+ require 'neo4j/active_node/property'
24
+ require 'neo4j/active_node/persistence'
25
+ require 'neo4j/active_node/validations'
26
+ require 'neo4j/active_node/rels'
27
+ require 'neo4j/active_node/has_n'
28
+ require 'neo4j/active_node/has_n/decl_rel'
29
+ require 'neo4j/active_node/has_n/nodes'
30
+ require 'neo4j/active_node'
@@ -0,0 +1,60 @@
1
+ module Neo4j
2
+
3
+ # Makes Neo4j nodes and relationships behave like active record objects.
4
+ # By including this module in your class it will create a mapping for the node to your ruby class
5
+ # by using a Neo4j Label with the same name as the class. When the node is loaded from the database it
6
+ # will check if there is a ruby class for the labels it has.
7
+ # If there Ruby class with the same name as the label then the Neo4j node will be wrapped
8
+ # in a new object of that class.
9
+ #
10
+ # = ClassMethods
11
+ # * {Neo4j::ActiveNode::Labels::ClassMethods} defines methods like: <tt>index</tt> and <tt>find</tt>
12
+ # * {Neo4j::ActiveNode::Persistence::ClassMethods} defines methods like: <tt>create</tt> and <tt>create!</tt>
13
+ # * {Neo4j::ActiveNode::Property::ClassMethods} defines methods like: <tt>property</tt>.
14
+ #
15
+ # @example Create a Ruby wrapper for a Neo4j Node
16
+ # class Company
17
+ # include Neo4j::ActiveNode
18
+ # property :name
19
+ # end
20
+ # company = Company.new
21
+ # company.name = 'My Company AB'
22
+ # Company.save
23
+ #
24
+ module ActiveNode
25
+ extend ActiveSupport::Concern
26
+ extend ActiveModel::Naming
27
+
28
+ include ActiveModel::Conversion
29
+ include ActiveModel::Serializers::Xml
30
+ include ActiveModel::Serializers::JSON
31
+ include Neo4j::ActiveNode::Initialize
32
+ include Neo4j::ActiveNode::Identity
33
+ include Neo4j::ActiveNode::Persistence
34
+ include Neo4j::ActiveNode::Property
35
+ include Neo4j::ActiveNode::Labels
36
+ include Neo4j::ActiveNode::Callbacks
37
+ include Neo4j::ActiveNode::Validations
38
+ include Neo4j::ActiveNode::Rels
39
+ include Neo4j::ActiveNode::HasN
40
+
41
+ def wrapper
42
+ self
43
+ end
44
+
45
+ def neo4j_obj
46
+ _persisted_node || raise("Tried to access native neo4j object on a none persisted object")
47
+ end
48
+
49
+
50
+ included do
51
+ def self.inherited(other)
52
+ attributes.each_pair do |k,v|
53
+ other.attributes[k] = v
54
+ end
55
+ Neo4j::ActiveNode::Labels.add_wrapped_class(other)
56
+ super
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
1
+ module Neo4j
2
+ module ActiveNode
3
+ module Callbacks #:nodoc:
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ include ActiveModel::Callbacks
8
+ end
9
+
10
+ included do
11
+ include ActiveModel::Validations::Callbacks
12
+
13
+ define_model_callbacks :initialize, :find, :only => :after
14
+ define_model_callbacks :save, :create, :update, :destroy
15
+ end
16
+
17
+ def destroy #:nodoc:
18
+ run_callbacks(:destroy) { super }
19
+ end
20
+
21
+ def touch(*) #:nodoc:
22
+ run_callbacks(:touch) { super }
23
+ end
24
+
25
+ private
26
+
27
+ def create_or_update #:nodoc:
28
+ run_callbacks(:save) { super }
29
+ end
30
+
31
+ def create_model #:nodoc:
32
+ run_callbacks(:create) { super }
33
+ end
34
+
35
+ def update_model(*) #:nodoc:
36
+ run_callbacks(:update) { super }
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,138 @@
1
+ module Neo4j::ActiveNode
2
+ module HasN
3
+ extend ActiveSupport::Concern
4
+
5
+ def _decl_rels_for(rel_type)
6
+ self.class._decl_rels[rel_type]
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def _decl_rels
12
+ @_decl_rels ||= {}
13
+ end
14
+
15
+ # make sure the inherited classes inherit the <tt>_decl_rels</tt> hash
16
+ def inherited(klass)
17
+ copy = _decl_rels.clone
18
+ copy.each_pair { |k, v| copy[k] = v.inherit_new }
19
+ klass.instance_variable_set(:@_decl_rels, copy)
20
+ super
21
+ end
22
+
23
+
24
+ # Specifies a relationship between two node active node classes.
25
+ # Generates assignment and accessor methods for the given relationship.
26
+ # Both incoming and outgoing relationships can be declared, see {Neo4j::ActiveNode::HasN::DeclRel}
27
+ #
28
+ # @example has_n(:files)
29
+ #
30
+ # class FolderNode
31
+ # include Neo4j::ActiveNode
32
+ # has_n(:files)
33
+ # end
34
+ #
35
+ # folder = FolderNode.new
36
+ # folder.files << Neo4j::Node.new << Neo4j::Node.new
37
+ # folder.files.inject {...}
38
+ #
39
+ # FolderNode.files #=> 'files' the name of the relationship
40
+ #
41
+ # @example has_n(x).to(...)
42
+ #
43
+ # # You can declare which class it has relationship to.
44
+ # # The generated relationships will be prefixed with the name of that class.
45
+ # class FolderNode
46
+ # include Neo4j::ActiveNode
47
+ # has_n(:files).to(File)
48
+ # # Same as has_n(:files).to("File")
49
+ # end
50
+ #
51
+ # FolderNode.files #=> 'File#files' the name of the relationship
52
+ #
53
+ # @example has_n(x).from(class, has_n_name)
54
+ #
55
+ # # generate accessor method for traversing and adding relationship on incoming nodes.
56
+ # class FileNode
57
+ # include Neo4j::ActiveNode
58
+ # has_one(:folder).from(FolderNode.files)
59
+ # # or same as
60
+ # has_one(:folder).from(FolderNode, :files)
61
+ # end
62
+ #
63
+ #
64
+ # @return [Neo4j::ActiveNode::HasN::DeclRel] a DSL object where the has_n relationship can be further specified
65
+ def has_n(rel_type)
66
+ clazz = self
67
+ module_eval(%Q{
68
+ def #{rel_type}()
69
+ dsl = _decl_rels_for('#{rel_type}'.to_sym)
70
+ Neo4j::ActiveNode::HasN::Nodes.new(self, dsl)
71
+ end}, __FILE__, __LINE__)
72
+
73
+
74
+ module_eval(%Q{
75
+ def #{rel_type}_rels
76
+ dsl = _decl_rels_for('#{rel_type}'.to_sym)
77
+ dsl.all_relationships(self)
78
+ end}, __FILE__, __LINE__)
79
+
80
+ instance_eval(%Q{
81
+ def #{rel_type}
82
+ _decl_rels[:#{rel_type}].rel_type
83
+ end}, __FILE__, __LINE__)
84
+
85
+ _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, false, clazz)
86
+ end
87
+
88
+
89
+ # Specifies a relationship between two node classes.
90
+ # Generates assignment and accessor methods for the given relationship
91
+ # Old relationship is deleted when a new relationship is assigned.
92
+ # Both incoming and outgoing relationships can be declared, see {Neo4j::Wrapper::HasN::DeclRel}
93
+ #
94
+ # @example
95
+ #
96
+ # class FileNode
97
+ # include Neo4j::ActiveNode
98
+ # has_one(:folder)
99
+ # end
100
+ #
101
+ # file = FileNode.create
102
+ # file.folder = Neo4j::Node.create
103
+ # file.folder # => the node above
104
+ # file.folder_rel # => the relationship object between those nodes
105
+ #
106
+ # @return [Neo4j::ActiveNode::HasN::DeclRel] a DSL object where the has_one relationship can be futher specified
107
+ def has_one(rel_type)
108
+ clazz = self
109
+ module_eval(%Q{def #{rel_type}=(value)
110
+ dsl = _decl_rels_for(:#{rel_type})
111
+ rel = dsl.single_relationship(self)
112
+ rel && rel.del
113
+ dsl.create_relationship_to(self, value) if value
114
+ end}, __FILE__, __LINE__)
115
+
116
+ module_eval(%Q{def #{rel_type}
117
+ dsl = _decl_rels_for('#{rel_type}'.to_sym)
118
+ dsl.single_node(self)
119
+ end}, __FILE__, __LINE__)
120
+
121
+ module_eval(%Q{def #{rel_type}_rel
122
+ dsl = _decl_rels_for(:#{rel_type})
123
+ dsl.single_relationship(self)
124
+ end}, __FILE__, __LINE__)
125
+
126
+ instance_eval(%Q{
127
+ def #{rel_type}
128
+ _decl_rels[:#{rel_type}].rel_type
129
+ end}, __FILE__, __LINE__)
130
+
131
+ _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, true, clazz)
132
+ end
133
+
134
+
135
+ end
136
+ end
137
+
138
+ end
@@ -0,0 +1,236 @@
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)
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
+ end
43
+
44
+ def inherit_new
45
+ base = self
46
+ dr = DeclRel.new(@method_id, @has_one, @source_class)
47
+ dr.instance_eval do
48
+ @dir = base.dir
49
+ @rel_type = base.rel_type
50
+ @target_name = base.target_name if base.target_name
51
+ @source_class = base.source_class
52
+ end
53
+ dr
54
+ end
55
+
56
+ def to_s
57
+ "DeclRel #{object_id} dir: #{@dir} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_name}"
58
+ end
59
+
60
+ # @return [true, false]
61
+ def has_one?
62
+ @has_one
63
+ end
64
+
65
+ # @return [true, false]
66
+ def has_n?
67
+ !@has_one
68
+ end
69
+
70
+ # @return [true,false]
71
+ def incoming? #:nodoc:
72
+ @dir == :incoming
73
+ end
74
+
75
+
76
+ # Declares an outgoing relationship type.
77
+ # It is possible to prefix relationship types so that it's possible to distinguish different incoming relationships.
78
+ # There is no validation that the added node is of the specified class.
79
+ #
80
+ # @example Example
81
+ # class FolderNode
82
+ # include Neo4j::ActiveNode
83
+ # has_n(:files).to(FileNode)
84
+ # has_one(:root).to("FileSystem") # also possible, if the class is not defined yet
85
+ # end
86
+ #
87
+ # folder = FolderNode.new
88
+ # # generate a relationship between folder and file of type 'FileNode#files'
89
+ # folder.files << FileNode.new
90
+ #
91
+ # @example relationship with a hash, user defined relationship
92
+ #
93
+ # class FolderNode
94
+ # include Neo4j::ActiveNode
95
+ # has_n(:files).to('FolderNode#files')
96
+ # end
97
+ #
98
+ # @example without prefix
99
+ #
100
+ # class FolderNode
101
+ # include Neo4j::ActiveNode
102
+ # has_n(:files).to(:contains)
103
+ # end
104
+ #
105
+ # file = FileNode.new
106
+ # # create an outgoing relationship of type 'contains' from folder node to file
107
+ # folder.files << FolderNode.new
108
+ #
109
+ # @param [Class, String, Symbol] target the other class to which this relationship goes (if String or Class) or the relationship (if Symbol)
110
+ # @param [String, Symbol] rel_type the rel_type postfix for the relationships, which defaults to the same as the has_n/one method id
111
+ # @return self
112
+ def to(target, rel_type = @method_id)
113
+ @dir = :outgoing
114
+
115
+ case target
116
+ when /#/
117
+ @target_name, _ = target.to_s.split("#")
118
+ @rel_type = target.to_sym
119
+ when Class, String
120
+ @target_name = target.to_s
121
+ @rel_type = "#{@source_class}##{rel_type}".to_sym
122
+ when Symbol
123
+ @target_name = nil
124
+ @rel_type = target.to_sym
125
+ else
126
+ raise "Expected a class or a symbol for, got #{target}/#{target.class}"
127
+ end
128
+ self
129
+ end
130
+
131
+ # Specifies an incoming relationship.
132
+ # Will use the outgoing relationship given by the from class.
133
+ #
134
+ # @example with prefix FileNode
135
+ # class FolderNode
136
+ # include Neo4j::NodeMixin
137
+ # has_n(:files).to(FileNode)
138
+ # end
139
+ #
140
+ # class FileNode
141
+ # include Neo4j::NodeMixin
142
+ # # will only traverse any incoming relationship of type files from node FileNode
143
+ # has_one(:folder).from(FolderNode.files)
144
+ # # alternative: has_one(:folder).from(FolderNode, :files)
145
+ # end
146
+ #
147
+ # file = FileNode.new
148
+ # # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
149
+ # file.folder = FolderNode.new
150
+ #
151
+ # @example without prefix
152
+ #
153
+ # class FolderNode
154
+ # include Neo4j::NodeMixin
155
+ # has_n(:files)
156
+ # end
157
+ #
158
+ # class FileNode
159
+ # include Neo4j::NodeMixin
160
+ # has_one(:folder).from(:files) # will traverse any incoming relationship of type files
161
+ # end
162
+ #
163
+ # file = FileNode.new
164
+ # # create an outgoing relationship of type 'files' from folder node to file
165
+ # file.folder = FolderNode.new
166
+ #
167
+ #
168
+ def from(target, rel_type=@method_id)
169
+ @dir = :incoming
170
+
171
+ case target
172
+ when /#/
173
+ @target_name, _ = target.to_s.split("#")
174
+ @rel_type = target
175
+ when Class, String
176
+ @target_name = target.to_s
177
+ @rel_type = "#{@target_name}##{rel_type}".to_sym
178
+ when Symbol
179
+ @target_name = nil
180
+ @rel_type = target.to_sym
181
+ else
182
+ raise "Expected a class or a symbol for, got #{target}/#{target.class}"
183
+ end
184
+ self
185
+ end
186
+
187
+
188
+ # @private
189
+ def target_name
190
+ @target_name
191
+ end
192
+
193
+ def target_class
194
+ @target_name && @target_name.split("::").inject(Kernel) { |container, name| container.const_get(name.to_s) }
195
+ end
196
+
197
+
198
+ # @private
199
+ def each_node(node, &block)
200
+ node.nodes(dir: dir, type: rel_type).each { |n| block.call(n)}
201
+ end
202
+
203
+ def all_relationships(node)
204
+ # TODO fix ruby warning - warning: Enumerator.new without a block is deprecated; use Object#to_enum
205
+ Enumerator.new(self, :each_rel, node)
206
+ end
207
+
208
+ def each_rel(node, &block) #:nodoc:
209
+ node.rels(dir: dir, type: rel_type).each { |rel| block.call(rel) }
210
+ end
211
+
212
+ def single_relationship(node)
213
+ node.rel(dir: dir, type: rel_type)
214
+ end
215
+
216
+ def single_node(node)
217
+ node.node(dir: dir, type: rel_type)
218
+ end
219
+
220
+ # @private
221
+ def _each_node(node, &block) #:nodoc:
222
+ node._rels(dir: dir, type: rel_type).each do |rel|
223
+ block.call rel._other_node(node)
224
+ end
225
+ end
226
+
227
+ # @private
228
+ def create_relationship_to(node, other) # :nodoc:
229
+ from, to = incoming? ? [other, node] : [node, other]
230
+ from.create_rel(@rel_type, to)
231
+ end
232
+
233
+ end
234
+ end
235
+ end
236
+ end