neo4j 2.0.0.alpha.5-java → 2.0.0.alpha.6-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/CHANGELOG +12 -0
  2. data/Gemfile +0 -4
  3. data/README.rdoc +106 -62
  4. data/lib/neo4j.rb +7 -33
  5. data/lib/neo4j/performance.rb +43 -0
  6. data/lib/neo4j/rails/accept_id.rb +19 -18
  7. data/lib/neo4j/rails/attributes.rb +366 -120
  8. data/lib/neo4j/rails/finders.rb +41 -15
  9. data/lib/neo4j/rails/has_n.rb +203 -0
  10. data/lib/neo4j/rails/identity.rb +25 -0
  11. data/lib/neo4j/rails/model.rb +65 -242
  12. data/lib/neo4j/rails/nested_attributes.rb +108 -0
  13. data/lib/neo4j/rails/node_persistance.rb +56 -0
  14. data/lib/neo4j/rails/observer.rb +0 -2
  15. data/lib/neo4j/rails/persistence.rb +32 -154
  16. data/lib/neo4j/rails/rack_middleware.rb +26 -2
  17. data/lib/neo4j/rails/rails.rb +9 -6
  18. data/lib/neo4j/rails/railtie.rb +1 -2
  19. data/lib/neo4j/rails/relationship.rb +18 -125
  20. data/lib/neo4j/rails/relationship_persistence.rb +107 -0
  21. data/lib/neo4j/rails/relationships/node_dsl.rb +72 -44
  22. data/lib/neo4j/rails/relationships/relationships.rb +187 -59
  23. data/lib/neo4j/rails/relationships/rels_dsl.rb +18 -17
  24. data/lib/neo4j/rails/relationships/storage.rb +19 -17
  25. data/lib/neo4j/rails/timestamps.rb +53 -51
  26. data/lib/neo4j/rails/transaction.rb +9 -1
  27. data/lib/neo4j/rails/validations/uniqueness.rb +1 -1
  28. data/lib/neo4j/rails/versioning/versioning.rb +2 -2
  29. data/lib/neo4j/version.rb +1 -1
  30. data/lib/orm_adapter/adapters/neo4j.rb +47 -46
  31. data/neo4j.gemspec +1 -1
  32. metadata +10 -69
  33. data/lib/neo4j/algo/algo.rb +0 -294
  34. data/lib/neo4j/batch/batch.rb +0 -4
  35. data/lib/neo4j/batch/indexer.rb +0 -109
  36. data/lib/neo4j/batch/inserter.rb +0 -179
  37. data/lib/neo4j/batch/rule_inserter.rb +0 -24
  38. data/lib/neo4j/batch/rule_node.rb +0 -72
  39. data/lib/neo4j/config.rb +0 -177
  40. data/lib/neo4j/core_ext/class/inheritable_attributes.rb +0 -12
  41. data/lib/neo4j/core_ext/class/rewrite_inheritable_attributes.rb +0 -170
  42. data/lib/neo4j/database.rb +0 -158
  43. data/lib/neo4j/equal.rb +0 -21
  44. data/lib/neo4j/event_handler.rb +0 -263
  45. data/lib/neo4j/has_list/class_methods.rb +0 -11
  46. data/lib/neo4j/has_list/has_list.rb +0 -3
  47. data/lib/neo4j/has_list/mapping.rb +0 -133
  48. data/lib/neo4j/has_n/class_methods.rb +0 -119
  49. data/lib/neo4j/has_n/decl_relationship_dsl.rb +0 -246
  50. data/lib/neo4j/has_n/has_n.rb +0 -3
  51. data/lib/neo4j/has_n/mapping.rb +0 -98
  52. data/lib/neo4j/identity_map.rb +0 -140
  53. data/lib/neo4j/index/class_methods.rb +0 -108
  54. data/lib/neo4j/index/index.rb +0 -39
  55. data/lib/neo4j/index/indexer.rb +0 -341
  56. data/lib/neo4j/index/indexer_registry.rb +0 -68
  57. data/lib/neo4j/index/lucene_query.rb +0 -256
  58. data/lib/neo4j/load.rb +0 -25
  59. data/lib/neo4j/migrations/class_methods.rb +0 -110
  60. data/lib/neo4j/migrations/extensions.rb +0 -58
  61. data/lib/neo4j/migrations/lazy_node_mixin.rb +0 -41
  62. data/lib/neo4j/migrations/migration.rb +0 -112
  63. data/lib/neo4j/migrations/migrations.rb +0 -6
  64. data/lib/neo4j/migrations/node_mixin.rb +0 -80
  65. data/lib/neo4j/migrations/ref_node_wrapper.rb +0 -32
  66. data/lib/neo4j/model.rb +0 -4
  67. data/lib/neo4j/neo4j.rb +0 -216
  68. data/lib/neo4j/node.rb +0 -270
  69. data/lib/neo4j/node_mixin/class_methods.rb +0 -51
  70. data/lib/neo4j/node_mixin/node_mixin.rb +0 -141
  71. data/lib/neo4j/paginated.rb +0 -23
  72. data/lib/neo4j/property/class_methods.rb +0 -79
  73. data/lib/neo4j/property/property.rb +0 -111
  74. data/lib/neo4j/rails/mapping/property.rb +0 -183
  75. data/lib/neo4j/rails/rel_persistence.rb +0 -237
  76. data/lib/neo4j/relationship.rb +0 -239
  77. data/lib/neo4j/relationship_mixin/class_methods.rb +0 -36
  78. data/lib/neo4j/relationship_mixin/relationship_mixin.rb +0 -142
  79. data/lib/neo4j/relationship_set.rb +0 -58
  80. data/lib/neo4j/rels/rels.rb +0 -110
  81. data/lib/neo4j/rels/traverser.rb +0 -102
  82. data/lib/neo4j/rule/class_methods.rb +0 -201
  83. data/lib/neo4j/rule/event_listener.rb +0 -66
  84. data/lib/neo4j/rule/functions/count.rb +0 -43
  85. data/lib/neo4j/rule/functions/function.rb +0 -74
  86. data/lib/neo4j/rule/functions/functions.rb +0 -3
  87. data/lib/neo4j/rule/functions/sum.rb +0 -29
  88. data/lib/neo4j/rule/rule.rb +0 -150
  89. data/lib/neo4j/rule/rule_node.rb +0 -217
  90. data/lib/neo4j/to_java.rb +0 -31
  91. data/lib/neo4j/transaction.rb +0 -73
  92. data/lib/neo4j/traversal/filter_predicate.rb +0 -25
  93. data/lib/neo4j/traversal/prune_evaluator.rb +0 -14
  94. data/lib/neo4j/traversal/rel_expander.rb +0 -31
  95. data/lib/neo4j/traversal/traversal.rb +0 -141
  96. data/lib/neo4j/traversal/traverser.rb +0 -284
  97. data/lib/neo4j/type_converters/type_converters.rb +0 -288
@@ -1,27 +1,30 @@
1
1
  # rails
2
2
  require 'neo4j/rails/tx_methods'
3
+ require 'neo4j/rails/identity'
3
4
  require 'neo4j/rails/transaction'
4
5
  require 'neo4j/rails/railtie'
5
6
  require 'neo4j/rails/validations/uniqueness'
6
7
  require 'neo4j/rails/validations/non_nil'
7
8
  require 'neo4j/rails/validations/associated'
8
9
  require 'neo4j/rails/finders'
9
- require 'neo4j/rails/mapping/property'
10
10
  require 'neo4j/rails/validations'
11
11
  require 'neo4j/rails/callbacks'
12
12
  require 'neo4j/rails/observer'
13
13
  require 'neo4j/rails/compositions'
14
14
  require 'neo4j/rails/accept_id'
15
15
  require 'neo4j/rails/timestamps'
16
- require 'neo4j/rails/serialization'
17
16
  require 'neo4j/rails/attributes'
17
+ require 'neo4j/rails/nested_attributes'
18
+ require 'neo4j/rails/serialization'
18
19
  require 'neo4j/rails/persistence'
20
+ require 'neo4j/rails/node_persistance'
21
+ require 'neo4j/rails/relationship_persistence'
19
22
  require 'neo4j/rails/relationships/storage'
20
23
  require 'neo4j/rails/relationships/node_dsl'
21
24
  require 'neo4j/rails/relationships/rels_dsl'
22
25
  require 'neo4j/rails/relationships/relationships'
23
- require 'neo4j/rails/model'
26
+ require 'neo4j/rails/has_n'
24
27
  require 'neo4j/rails/rack_middleware'
25
- require 'neo4j/rails/rel_persistence'
26
- require 'neo4j/rails/relationship'
27
- require 'neo4j/rails/versioning/versioning'
28
+ require 'neo4j/rails/versioning/versioning'
29
+ require 'neo4j/rails/model'
30
+ require 'neo4j/rails/relationship'
@@ -3,8 +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::RackMiddleware
7
- app.config.middleware.use Neo4j::IdentityMap::Middleware
6
+ app.config.middleware.use Neo4j::Rails::Middleware
8
7
  end
9
8
 
10
9
  # Add ActiveModel translations to the I18n load_path
@@ -1,6 +1,5 @@
1
1
  module Neo4j
2
2
  module Rails
3
-
4
3
  # Includes the Neo4j::RelationshipMixin and adds ActiveRecord/Model like behaviour.
5
4
  # That means for example that you don't have to care about transactions since they will be
6
5
  # automatically be created when needed.
@@ -12,146 +11,40 @@ module Neo4j
12
11
  # It also implement timestamps (like active record), just add a updated_at or created_at attribute.
13
12
  #
14
13
  class Relationship
15
- include Neo4j::RelationshipMixin
16
-
17
- # The relationship type
18
- attr_reader :type
19
-
20
- index :_classname
21
-
22
- # Initialize a Node with a set of properties (or empty if nothing is passed)
23
- def initialize(*args)
24
- @properties_before_type_cast=java.util.HashMap.new
25
- @type = args[0].to_s
26
- self.start_node = args[1]
27
- self.end_node = args[2]
28
- attributes = args[3]
29
- reset_attributes
30
- self.attributes = attributes if attributes.is_a?(Hash)
31
- end
32
-
33
- def other_node(node)
34
- if persisted?
35
- _java_rel.getOtherNode(node._java_node)
36
- else
37
- @start_node == (node._java_node || node) ? @end_node : @start_node
38
- end
39
- end
40
-
41
-
42
- alias_method :get_other_node, :other_node # so it looks like the java version
14
+ extend ActiveModel::Translation
43
15
 
44
- def attribute_missing(method_id, *args, &block)
45
- method_name = method_id.method_name
46
- if property?(method_name)
47
- self[method_name]
48
- else
49
- super
50
- end
51
- end
16
+ include Neo4j::RelationshipMixin
17
+ include ActiveModel::Dirty # track changes to attributes
18
+ include ActiveModel::MassAssignmentSecurity # handle attribute hash assignment
19
+ include ActiveModel::Observing # enable observers
20
+ include Neo4j::Rails::Identity
21
+ include Neo4j::Rails::Persistence # handles how to save, create and update the model
22
+ include Neo4j::Rails::RelationshipPersistence # handles how to save, create and update the model
23
+ include Neo4j::Rails::Attributes # handles how to save and retrieve attributes
24
+ include Neo4j::Rails::Serialization # enable to_xml and to_json
25
+ include Neo4j::Rails::Validations # enable validations
26
+ include Neo4j::Rails::Callbacks # enable callbacks
27
+ include Neo4j::Rails::Timestamps # handle created_at, updated_at timestamp properties
28
+ include Neo4j::Rails::Finders # ActiveRecord style find
29
+ include Neo4j::Rails::Compositions
30
+
31
+ index :_classname # since there are no rule we have to use lucene to find all instance of a class
52
32
 
53
- def rel_type
54
- persisted? ? _java_entity.rel_type : @type
55
- end
56
33
 
57
34
  def to_s
58
35
  "id: #{self.object_id} start_node: #{start_node.id} end_node: #{end_node.id} type:#{@type}"
59
36
  end
60
37
 
61
- def id
62
- _java_rel.nil? || neo_id.nil? ? nil : neo_id.to_s
63
- end
64
-
65
- def hash
66
- persisted? ? _java_entity.neo_id.hash : super
67
- end
68
-
69
- def start_node
70
- @start_node ||= _java_rel && _java_rel.start_node
71
- end
72
-
73
- def start_node=(node)
74
- old = @start_node
75
- @start_node = node
76
- # TODO should raise exception if not persisted and changed
77
- if old != @start_node
78
- old && old.rm_outgoing_rel(type, self)
79
- @start_node.class != Neo4j::Node && @start_node.add_outgoing_rel(type, self)
80
- end
81
- end
82
-
83
- def end_node
84
- @end_node ||= _java_rel && _java_rel.end_node
85
- end
86
-
87
- def end_node=(node)
88
- old = @end_node
89
- @end_node = node
90
- # TODO should raise exception if not persisted and changed
91
- if old != @end_node
92
- old && old.rm_incoming_rel(type, self)
93
- @end_node.class != Neo4j::Node && @end_node.add_incoming_rel(type, self)
94
- end
95
- end
96
-
97
- def del
98
- _java_rel.del
99
- end
100
-
101
- def reset_attributes
102
- @properties = {}
103
- end
104
-
105
- def wrapper
106
- self
107
- end
108
-
109
38
  # --------------------------------------
110
39
  # Public Class Methods
111
40
  # --------------------------------------
112
41
  class << self
113
- # NodeMixin overwrites the #new class method but it saves it as orig_new
114
- # Here, we just get it back to normal
115
- alias :new :orig_new
116
-
117
- def entity_load(id)
118
- Neo4j::Relationship.load(id)
119
- end
120
-
121
-
122
- def rule(*)
123
- end
124
-
125
42
  def _all
126
43
  _indexer.find(:_classname => self)
127
44
  end
128
-
129
- def load(*ids) # TODO Copied from finders.rb
130
- result = ids.map { |id| entity_load(id) }
131
- if ids.length == 1
132
- result.first
133
- else
134
- result
135
- end
136
- end
137
-
138
45
  end
139
46
 
140
47
  end
141
48
 
142
-
143
- Relationship.class_eval do
144
- extend ActiveModel::Translation
145
- include RelPersistence # handles how to save, create and update the model
146
- include Attributes # handles how to save and retrieve attributes
147
- include Mapping::Property # allows some additional options on the #property class method
148
- include Serialization # enable to_xml and to_json
149
- include Validations # enable validations
150
- include Callbacks # enable callbacks
151
- include Timestamps # handle created_at, updated_at timestamp properties
152
- include Finders # ActiveRecord style find
153
- include Compositions
154
- end
155
-
156
49
  end
157
- end
50
+ end
@@ -0,0 +1,107 @@
1
+ module Neo4j
2
+ module Rails
3
+ module RelationshipPersistence
4
+ extend TxMethods
5
+
6
+ # Initialize a Node with a set of properties (or empty if nothing is passed)
7
+ def initialize(*args)
8
+ return initialize_attributes(nil) if args.size < 3 # then we have been loaded
9
+ type, start_node, end_node, attributes = args
10
+ @_rel_type = type.to_sym
11
+ raise "Unknown type" unless type
12
+ raise "Unknown start_node" unless start_node
13
+ raise "Unknown end_node" unless end_node
14
+ self.start_node = start_node
15
+ self.end_node = end_node
16
+ initialize_attributes(attributes)
17
+ end
18
+
19
+
20
+ def create
21
+ # prevent calling create twice
22
+ @_start_node.add_unpersisted_outgoing_rel(rel_type, self)
23
+ @_end_node.add_unpersisted_incoming_rel(rel_type, self)
24
+
25
+ return unless _persist_node(@_start_node) && _persist_node(@_end_node)
26
+
27
+ java_rel = Neo4j::Relationship.new(rel_type, start_node, end_node)
28
+ init_on_load(java_rel)
29
+ Neo4j::IdentityMap.add(java_rel, self)
30
+ init_on_create
31
+
32
+ @_start_node.rm_unpersisted_outgoing_rel(rel_type, self)
33
+ @_end_node.rm_unpersisted_incoming_rel(rel_type, self)
34
+ true
35
+ end
36
+
37
+ def rel_type
38
+ new_record? ? @_rel_type : _java_entity.rel_type.to_sym
39
+ end
40
+
41
+ def other_node(node)
42
+ if persisted?
43
+ _java_rel._other_node(node._java_node)
44
+ else
45
+ @_start_node == (node._java_node || node) ? @_end_node : @_start_node
46
+ end
47
+ end
48
+
49
+
50
+ def start_node
51
+ @_start_node ||= _java_rel && _java_rel.start_node.wrapper
52
+ end
53
+
54
+ def start_node=(node)
55
+ old = @_start_node
56
+ @_start_node = node
57
+ # TODO should raise exception if not persisted and changed
58
+ if old != @_start_node
59
+ old && old.rm_outgoing_rel(rel_type, self)
60
+ @_start_node.class != Neo4j::Node && @_start_node.add_outgoing_rel(rel_type, self)
61
+ end
62
+ end
63
+
64
+ def end_node
65
+ @_end_node ||= _java_rel && _java_rel.end_node.wrapper
66
+ end
67
+
68
+ def end_node=(node)
69
+ old = @_end_node
70
+ @_end_node = node
71
+ # TODO should raise exception if not persisted and changed
72
+ if old != @_end_node
73
+ old && old.rm_incoming_rel(rel_type, self)
74
+ @_end_node.class != Neo4j::Node && @_end_node.add_incoming_rel(rel_type, self)
75
+ end
76
+ end
77
+
78
+
79
+ def _persist_node(start_or_end_node)
80
+ (start_or_end_node.new_record? || start_or_end_node.relationships_changed?) ? start_or_end_node.save : true
81
+ end
82
+
83
+ # Reload the object from the DB
84
+ def reload(options = nil)
85
+ raise "Can't reload a none persisted node" if new_record?
86
+ clear_changes
87
+ reset_attributes
88
+ unless reload_from_database
89
+ set_deleted_properties
90
+ freeze
91
+ end
92
+ self
93
+ end
94
+
95
+
96
+ def reload_from_database
97
+ Neo4j::IdentityMap.remove_rel_by_id(id) if persisted?
98
+ if reloaded = self.class.load_entity(id)
99
+ send(:attributes=, reloaded.attributes, false)
100
+ end
101
+ reloaded
102
+ end
103
+ end
104
+
105
+ end
106
+ end
107
+
@@ -5,7 +5,7 @@ module Neo4j
5
5
  # Instances of this class is returned from the #outgoing, #incoming and generated accessor methods:
6
6
  # has_n and has_one.
7
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(...)).
8
+ # If you want to full traversal api use the core version of these methods (some_node._outgoing(...)).
9
9
  #
10
10
  class NodesDSL
11
11
  include Enumerable
@@ -19,8 +19,7 @@ module Neo4j
19
19
  # The new node and relationship will not be saved.
20
20
  # Both the relationship class and the node class can be specified with the has_n and has_one.
21
21
  #
22
- # ==== Example
23
- #
22
+ # @example
24
23
  # class Person < Neo4j::Rails::Model
25
24
  # has_n(:friends).to(Person).relationship(Friend)
26
25
  # has_n(:knows)
@@ -28,13 +27,16 @@ module Neo4j
28
27
  #
29
28
  # Person.friends.build(:name => 'kalle') # creates a Person and Friends class.
30
29
  # Person.knows.build(:name => 'kalle') # creates a Neo4j::Rails::Model and Neo4j::Rails::Relationship class
31
- #
32
- def build(attrs = {})
30
+ # @param [Hash] attrs the attributes for the created node
31
+ # @return [Neo4j::Rails::Model]
32
+ def build(attrs = {})
33
33
  self << (node = @storage.build(attrs))
34
34
  node
35
35
  end
36
36
 
37
37
  # Same as #build except that the relationship and node are saved.
38
+ # @param (see #build)
39
+ # @return [Neo4j::Rails::Model]
38
40
  def create(attrs = {})
39
41
  self << (node = @storage.create(attrs))
40
42
  node.save
@@ -42,13 +44,24 @@ module Neo4j
42
44
  end
43
45
 
44
46
  # Same as #create but will raise an exception if an error (like validation) occurs.
47
+ # @param (see #build)
48
+ # @return [Neo4j::Rails::Model]
45
49
  def create!(attrs)
46
50
  self << (node = @storage.create(attrs))
47
51
  node.save!
48
52
  node
49
53
  end
50
54
 
51
- # Adds a new node to the relationship
55
+ # Adds a new node to the relationship, no transaction is needed.
56
+ #
57
+ # @example create a relationship between two nodes
58
+ # node.friends << other
59
+ #
60
+ # @example using existing nodes
61
+ # node.friends = ['42', '32']
62
+ #
63
+ # @param [String, Neo4j::Rails::Model] other
64
+ # @return self
52
65
  def <<(other)
53
66
  if other.is_a?(String)
54
67
  # this is typically called in an assignment operator, person.friends = ['42', '32']
@@ -69,20 +82,11 @@ module Neo4j
69
82
  all.to_a
70
83
  end
71
84
 
72
- # Specifies the depth of the traversal
73
- def depth(d)
74
- adapt_to_traverser.depth(d)
75
- end
76
-
77
- def adapt_to_traverser # :nodoc:
78
- Neo4j::Traversal::Traverser.new(@storage.node, @storage.rel_type, @dir)
79
- end
80
-
81
85
  # Returns the n:th item in the relationship.
82
86
  # This method simply traverse all relationship and returns the n:th one.
83
87
  def [](index)
84
88
  i = 0
85
- each{|x| return x if i == index; i += 1}
89
+ each { |x| return x if i == index; i += 1 }
86
90
  nil # out of index
87
91
  end
88
92
 
@@ -94,32 +98,33 @@ module Neo4j
94
98
 
95
99
  # Find one node in the relationship.
96
100
  #
97
- # ==== Example
101
+ # @example Declaration of the relationship used in the examples below
98
102
  #
99
103
  # class Actor < Neo4j::Rails::Model
100
104
  # has_n(:acted_in)
101
105
  # end
102
106
  #
103
- # # find all child nodes
104
- # actor.acted_in.find(:all)
107
+ # @example find all child nodes
108
+ # actor.acted_in.find(:all)
105
109
  #
106
- # # find first child node
107
- # actor.acted_in.find(:first)
110
+ # @example find first child node
111
+ # actor.acted_in.find(:first)
108
112
  #
109
- # # find a child node by node
110
- # actor.acted_in.find(some_movie)
113
+ # @example find a child node by node
114
+ # actor.acted_in.find(some_movie)
111
115
  #
112
- # # find a child node by id" do
113
- # actor.acted_in.find(some_movie.id)
116
+ # @example find a child node by id" do
117
+ # actor.acted_in.find(some_movie.id)
114
118
  #
115
- # #find a child node by delegate to Enumerable#find
116
- # actor.acted_in.find{|n| n.title == 'movie_1'}
119
+ # @example find a child node by delegate to Enumerable#find
120
+ # actor.acted_in.find{|n| n.title == 'movie_1'}
117
121
  #
122
+ # @return [Neo4j::Rails::Model]
118
123
  def find(*args, &block)
119
124
  return super(*args, &block) if block
120
-
125
+
121
126
  case args.first
122
- when :all, :first
127
+ when :all, :first
123
128
  kind = args.shift
124
129
  send(kind, *args)
125
130
  when "0", 0
@@ -130,14 +135,14 @@ module Neo4j
130
135
  else
131
136
  first(*args)
132
137
  end
133
- end
138
+ end
134
139
  end
135
140
 
136
141
  # Same as #find except that it returns an Enumerator of all nodes found.
137
142
  #
138
143
  def all(*args)
139
144
  unless args.empty?
140
- enum = Enumerator.new(@storage, :each_node, @dir).find{|n| n == args.first}
145
+ enum = Enumerator.new(@storage, :each_node, @dir).find { |n| n == args.first }
141
146
  else
142
147
  enum = Enumerator.new(@storage, :each_node, @dir)
143
148
  end
@@ -148,7 +153,7 @@ module Neo4j
148
153
  if result = all(*args)
149
154
  if result.respond_to?(:collect) #if it's enumerable, get the first result
150
155
  result.first
151
- else
156
+ else
152
157
  result
153
158
  end
154
159
  else
@@ -156,36 +161,40 @@ module Neo4j
156
161
  end
157
162
  end
158
163
 
159
- # Destroys all nodes (!!!) and relationship in this relatationship.
160
- # Notice, if you only want to destroy the relationship use the
164
+ # Destroys all nodes (!) and relationship.
165
+ # Notice, if you only want to destroy the relationship use the #rels(:friends).destroy_all method instead.
161
166
  def destroy_all
162
- each {|n| n.destroy}
167
+ each { |n| n.destroy }
163
168
  end
164
169
 
170
+ # Deletes all nodes and relationships, similar to #destroy_all
165
171
  def delete_all
166
- each {|n| n.delete}
172
+ each { |n| n.delete }
167
173
  end
168
174
 
169
- def size
170
- @storage.size(@dir)
175
+ # Counts all relationships
176
+ def count
177
+ @storage.count(@dir)
171
178
  end
172
179
 
173
- alias :length :size
180
+ alias :length :count
174
181
 
175
182
  def each
176
- @storage.each_node(@dir) {|n| yield n} # Why passing the &block through doesn't work on JRuby 1.9?
183
+ @storage.each_node(@dir) { |n| yield n } # Why passing the &block through doesn't work on JRuby 1.9?
177
184
  end
178
185
 
186
+ # Delete relationships to the given nodes
187
+ # @param [Neo4j::Rails::Model] nodes a list of nodes we want to delete relationships to
179
188
  def delete(*nodes)
180
189
  @storage.destroy_rels(@dir, *nodes)
181
190
  end
182
191
 
183
192
  def empty?
184
- size == 0 # TODO, performance: there are probably faster way of doing this
193
+ !@storage.relationships?(@dir)
185
194
  end
186
195
 
187
196
  def blank?
188
- false unless size == 0
197
+ false unless empty?
189
198
  end
190
199
 
191
200
  def to_s
@@ -196,13 +205,32 @@ module Neo4j
196
205
  @storage.persisted?
197
206
  end
198
207
 
208
+
209
+ # These methods are using the Neo4j::Core::Traversal::Traverser which means that only persisted relationship will be seen
210
+ # but more advanced traversal can be performed.
211
+ CORE_TRAVERSAL_METHODS = [:depth, :outgoing, :incoming, :both, :expand, :depth_first, :breadth_first, :eval_paths, :unique, :expander, :prune, :filter, :include_start_node, :rels, :eval_paths]
212
+
213
+
199
214
  protected
200
215
 
216
+ def self.define_traversal_method(method_name)
217
+ class_eval <<-RUBY, __FILE__, __LINE__
218
+ def #{method_name}(*args, &block)
219
+ if block
220
+ Neo4j::Core::Traversal::Traverser.new(@storage.node, @dir, @storage.rel_type).send(:"#{method_name}", *args, &block)
221
+ else
222
+ Neo4j::Core::Traversal::Traverser.new(@storage.node, @dir, @storage.rel_type).send(:"#{method_name}", *args)
223
+ end
224
+ end
225
+ RUBY
226
+ end
227
+
228
+ CORE_TRAVERSAL_METHODS.each { |meth| define_traversal_method(meth)}
201
229
 
202
230
  def find_by_id(*args)
203
- result = Enumerator.new(@storage, :each_node, @dir).find{|n| n.id.to_i == args.first.to_i}
231
+ result = Enumerator.new(@storage, :each_node, @dir).find { |n| n.id.to_i == args.first.to_i }
204
232
  end
205
-
233
+
206
234
  end
207
235
  end
208
236
  end