neo4j 1.3.0-java → 1.3.1-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.
Files changed (40) hide show
  1. data/CHANGELOG +14 -0
  2. data/CONTRIBUTORS +1 -0
  3. data/Gemfile +7 -0
  4. data/README.rdoc +6 -3
  5. data/lib/neo4j.rb +13 -13
  6. data/lib/neo4j/algo/algo.rb +2 -2
  7. data/lib/neo4j/database.rb +1 -1
  8. data/lib/neo4j/has_n/decl_relationship_dsl.rb +11 -8
  9. data/lib/neo4j/identity_map.rb +0 -3
  10. data/lib/neo4j/index/lucene_query.rb +50 -9
  11. data/lib/neo4j/jars/core/{neo4j-community-1.5.jar → neo4j-community-1.6.M01.jar} +0 -0
  12. data/lib/neo4j/jars/core/{neo4j-cypher-1.5.jar → neo4j-cypher-1.6.M01.jar} +0 -0
  13. data/lib/neo4j/jars/core/{neo4j-graph-algo-1.5.jar → neo4j-graph-algo-1.6.M01.jar} +0 -0
  14. data/lib/neo4j/jars/core/{neo4j-graph-matching-1.5.jar → neo4j-graph-matching-1.6.M01.jar} +0 -0
  15. data/lib/neo4j/jars/core/{neo4j-jmx-1.5.jar → neo4j-jmx-1.6.M01.jar} +0 -0
  16. data/lib/neo4j/jars/core/{neo4j-kernel-1.5.jar → neo4j-kernel-1.6.M01.jar} +0 -0
  17. data/lib/neo4j/jars/core/{neo4j-lucene-index-1.5.jar → neo4j-lucene-index-1.6.M01.jar} +0 -0
  18. data/lib/neo4j/jars/core/{neo4j-shell-1.5.jar → neo4j-shell-1.6.M01.jar} +0 -0
  19. data/lib/neo4j/jars/core/{neo4j-udc-1.5.jar → neo4j-udc-1.6.M01.jar} +0 -0
  20. data/lib/neo4j/jars/core/{server-api-1.5.jar → server-api-1.6.M01.jar} +0 -0
  21. data/lib/neo4j/jars/ha/{neo4j-backup-1.5.jar → neo4j-backup-1.6.M01.jar} +0 -0
  22. data/lib/neo4j/jars/ha/{neo4j-com-1.5.jar → neo4j-com-1.6.M01.jar} +0 -0
  23. data/lib/neo4j/jars/ha/{neo4j-enterprise-1.5.jar → neo4j-enterprise-1.6.M01.jar} +0 -0
  24. data/lib/neo4j/jars/ha/neo4j-ha-1.6.M01.jar +0 -0
  25. data/lib/neo4j/jars/ha/{neo4j-management-1.5.jar → neo4j-management-1.6.M01.jar} +0 -0
  26. data/lib/neo4j/jars/neo4j-community-1.6.M01.jar +0 -0
  27. data/lib/neo4j/rails/accept_id.rb +66 -0
  28. data/lib/neo4j/rails/mapping/property.rb +1 -2
  29. data/lib/neo4j/rails/model.rb +1 -0
  30. data/lib/neo4j/rails/observer.rb +61 -2
  31. data/lib/neo4j/rails/persistence.rb +1 -1
  32. data/lib/neo4j/rails/rails.rb +1 -0
  33. data/lib/neo4j/rails/rel_persistence.rb +10 -11
  34. data/lib/neo4j/rails/relationships/node_dsl.rb +5 -1
  35. data/lib/neo4j/rails/relationships/relationships.rb +34 -0
  36. data/lib/neo4j/rails/relationships/storage.rb +34 -5
  37. data/lib/neo4j/type_converters/type_converters.rb +49 -4
  38. data/lib/neo4j/version.rb +1 -1
  39. metadata +19 -17
  40. data/lib/neo4j/jars/ha/neo4j-ha-1.5.jar +0 -0
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ == 1.3.1 / 2011-12-14
2
+ * Make all relationships visible in Rails callback (rspecs #87, Dmytrii Nagirniak) [#211]
3
+ * Enable travis to build JRuby 1.9 (pull #87, Dmytrii Nagirniak) [#214]
4
+ * Support for composite lucene queries with OR and NOT (pull #89, Deepak N)
5
+ * Enforce the correct converter on a property type when the type is given (pull #86, Dmytrii Nagirniak)
6
+ * Development: make it easier to run RSpecs and guard (pull #85, Dmytrii Nagirniak)
7
+ * Added ability to disable observer (pull #84, Dmytrii Nagirniak)
8
+ * Fixing multiple assignment of has_one assocaition (pull #83 Deepak N)
9
+ * Accept association_id for has_one assocations (pull #82, Deepak N)
10
+ * Upgrade to 1.6.M01 Neo4j java jars [#209]
11
+ * Defer warning message 'Unknown outgoing relationship' (pull #81, Vivek Prahlad)
12
+ * Added string converter, e.g. property :name, :type => String (pull #80, Dmytrii Nagirniak)
13
+ * Added symbol converter e.g. property :status, :type => Symbol (pull #79, Dmytrii Nagirniak) [#205]
14
+
1
15
  == 1.3.0 / 2011-12-06
2
16
  * Added neo4j-upgrade script to rename lucene index files and upgrade to 1.5 [#197]
3
17
  * Expose Neo4j::NodeMixin#index_types returning available indices (useful for Cypher queries) [#194]
data/CONTRIBUTORS CHANGED
@@ -2,6 +2,7 @@ Maintainer:
2
2
  Andreas Ronge <andreas dot ronge at gmail dot com>
3
3
 
4
4
  Contributors:
5
+ * Dmytrii Nagirniak
5
6
  * Marcio Toshio
6
7
  * Kalyan Akella
7
8
  * Vivek Prahlad
data/Gemfile CHANGED
@@ -8,6 +8,13 @@ group 'test' do
8
8
  gem "horo", ">= 1.0.2"
9
9
  gem "rspec", "= 2.6.0"
10
10
 
11
+ gem 'guard'
12
+ gem 'ruby_gntp', :require => false # GrowlNotify for Mac
13
+ gem 'rb-inotify', :require => false
14
+ gem 'rb-fsevent', :require => false
15
+ gem 'rb-fchange', :require => false
16
+ gem "guard-rspec"
17
+
11
18
  # use this version for rspec-rails-matchers which work with latest RSpec (Rspec => RSpec)
12
19
  gem "rspec-rails-matchers", :git => 'git://github.com/afcapel/rspec-rails-matchers.git'
13
20
 
data/README.rdoc CHANGED
@@ -126,17 +126,20 @@ Notice that you can always access the lower layers if you want to do some more a
126
126
 
127
127
  === Project information
128
128
  * {GitHub}[http://github.com/andreasronge/neo4j/tree/master]
129
- * {Lighthouse Issue Tracking}[http://neo4j.lighthouseapp.com]
129
+ * {Issue Tracking}[https://github.com/andreasronge/neo4j/issues]
130
130
  * {Twitter}[http://twitter.com/ronge]
131
- * IRC - #neo4j @ irc.freenode.net
132
131
  * {Mailing list, neo4jrb@googlegroups.com}[http://groups.google.com/group/neo4jrb]
132
+ * {Read only, old lighthouse issues}[http://neo4j.lighthouseapp.com]
133
133
 
134
134
  === Contributing
135
135
 
136
+ {<img src="https://secure.travis-ci.org/andreasronge/neo4j.png" />}[http://travis-ci.org/andreasronge/neo4j]
137
+
138
+ {Development configuration}[http://neo4j.rubyforge.org/guides/index.html#development-and-testing-configuration]
139
+
136
140
  Have you found a bug, need help or have a patch ?
137
141
  Just clone neo4j.rb and send me a pull request or email me.
138
142
  Do you need help - send me an email (andreas.ronge at gmail dot com).
139
- Please also check/add issues at lighthouse, http://neo4j.lighthouseapp.com
140
143
 
141
144
  === License
142
145
  * Neo4j.rb - MIT, see the LICENSE file http://github.com/andreasronge/neo4j/tree/master/LICENSE.
data/lib/neo4j.rb CHANGED
@@ -20,15 +20,15 @@ require 'neo4j/core_ext/class/inheritable_attributes'
20
20
 
21
21
  require 'neo4j/jars/core/geronimo-jta_1.1_spec-1.1.1.jar'
22
22
  require 'neo4j/jars/core/lucene-core-3.1.0.jar'
23
- require 'neo4j/jars/core/neo4j-cypher-1.5.jar'
24
- require 'neo4j/jars/core/neo4j-kernel-1.5.jar'
25
- require 'neo4j/jars/core/neo4j-lucene-index-1.5.jar'
26
- require 'neo4j/jars/core/neo4j-jmx-1.5.jar'
27
- require 'neo4j/jars/core/neo4j-udc-1.5.jar'
23
+ require 'neo4j/jars/core/neo4j-cypher-1.6.M01.jar'
24
+ require 'neo4j/jars/core/neo4j-kernel-1.6.M01.jar'
25
+ require 'neo4j/jars/core/neo4j-lucene-index-1.6.M01.jar'
26
+ require 'neo4j/jars/core/neo4j-jmx-1.6.M01.jar'
27
+ require 'neo4j/jars/core/neo4j-udc-1.6.M01.jar'
28
28
  require 'neo4j/jars/core/org.apache.servicemix.bundles.jline-0.9.94_1.jar'
29
29
  require 'neo4j/jars/core/scala-library-2.9.0-1.jar'
30
- require 'neo4j/jars/core/server-api-1.5.jar'
31
- require 'neo4j/jars/ha/neo4j-management-1.5.jar'
30
+ require 'neo4j/jars/core/server-api-1.6.M01.jar'
31
+ require 'neo4j/jars/ha/neo4j-management-1.6.M01.jar'
32
32
 
33
33
  module Neo4j
34
34
 
@@ -39,20 +39,20 @@ module Neo4j
39
39
  end
40
40
 
41
41
  def self.load_shell_jars
42
- require 'neo4j/jars/core/neo4j-shell-1.5.jar'
42
+ require 'neo4j/jars/core/neo4j-shell-1.6.M01.jar'
43
43
  end
44
44
 
45
45
  def self.load_online_backup
46
- require 'neo4j/jars/ha/neo4j-com-1.5.jar'
47
- require 'neo4j/jars/ha/neo4j-backup-1.5.jar'
46
+ require 'neo4j/jars/ha/neo4j-com-1.6.M01.jar'
47
+ require 'neo4j/jars/ha/neo4j-backup-1.6.M01.jar'
48
48
  require 'neo4j/jars/ha/org.apache.servicemix.bundles.netty-3.2.5.Final_1.jar'
49
49
  Neo4j.send(:const_set, :OnlineBackup, org.neo4j.backup.OnlineBackup)
50
50
  end
51
51
 
52
52
  def self.load_ha_jars
53
- require 'neo4j/jars/ha/neo4j-backup-1.5.jar'
54
- require 'neo4j/jars/ha/neo4j-com-1.5.jar'
55
- require 'neo4j/jars/ha/neo4j-ha-1.5.jar'
53
+ require 'neo4j/jars/ha/neo4j-backup-1.6.M01.jar'
54
+ require 'neo4j/jars/ha/neo4j-com-1.6.M01.jar'
55
+ require 'neo4j/jars/ha/neo4j-ha-1.6.M01.jar'
56
56
  require 'neo4j/jars/ha/log4j-1.2.16.jar'
57
57
  require 'neo4j/jars/ha/org.apache.servicemix.bundles.netty-3.2.5.Final_1.jar'
58
58
  require 'neo4j/jars/ha/slf4j-api-1.6.1.jar'
@@ -1,7 +1,7 @@
1
1
  # external neo4j dependencies
2
2
  require 'neo4j/to_java'
3
- require 'neo4j/jars/core/neo4j-graph-algo-1.5.jar'
4
- require 'neo4j/jars/core/neo4j-graph-matching-1.5.jar'
3
+ require 'neo4j/jars/core/neo4j-graph-algo-1.6.M01.jar'
4
+ require 'neo4j/jars/core/neo4j-graph-matching-1.6.M01.jar'
5
5
 
6
6
  module Neo4j
7
7
 
@@ -106,7 +106,7 @@ module Neo4j
106
106
  # Returns true if the neo4j db was started in read only mode.
107
107
  # This can occur if the database was locked (it was already one instance running).
108
108
  def read_only?
109
- @graph.isReadOnly
109
+ @graph.java_class == org.neo4j.kernel.EmbeddedGraphDatabase
110
110
  end
111
111
 
112
112
  # check if the database is locked. A neo4j database is locked when the database is running.
@@ -63,7 +63,7 @@ module Neo4j
63
63
  def java_dir
64
64
  dir_to_java(@dir)
65
65
  end
66
-
66
+
67
67
  def each_node(node, &block) #:nodoc:
68
68
  node._java_node.getRelationships(java_rel_type, java_dir).each do |rel|
69
69
  block.call(rel.getOtherNode(node).wrapper)
@@ -194,12 +194,7 @@ module Neo4j
194
194
  # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
195
195
  @rel_type = "#{@target_class}##{args[1]}"
196
196
  @target_class = args[0]
197
- other_class_dsl = @target_class._decl_rels[args[1]]
198
- if other_class_dsl
199
- @relationship = other_class_dsl.relationship_class
200
- else
201
- Neo4j.logger.warn "Unknown outgoing relationship #{args[1]} on #{@target_class}"
202
- end
197
+ @relationship_name = args[1]
203
198
  elsif (Symbol === args[0])
204
199
  # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
205
200
  @rel_type = args[0]
@@ -235,7 +230,15 @@ module Neo4j
235
230
  end
236
231
 
237
232
  def relationship_class # :nodoc:
238
- @relationship
233
+ if !@relationship_name.nil? && @relationship.nil?
234
+ other_class_dsl = @target_class._decl_rels[@relationship_name]
235
+ if other_class_dsl
236
+ @relationship = other_class_dsl.relationship_class
237
+ else
238
+ Neo4j.logger.warn "Unknown outgoing relationship #{@relationship_name} on #{@target_class}"
239
+ end
240
+ end
241
+ @relationship
239
242
  end
240
243
  end
241
244
  end
@@ -1,6 +1,3 @@
1
- # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/identity_map.rb
2
- # https://github.com/rails/rails/pull/76
3
-
4
1
  module Neo4j
5
2
 
6
3
  # = Neo4j Identity Map
@@ -38,7 +38,7 @@ module Neo4j
38
38
  class LuceneQuery
39
39
  include Enumerable
40
40
  include WillPaginate::Finders::Base
41
- attr_accessor :left_and_query, :left_or_query
41
+ attr_accessor :left_and_query, :left_or_query, :right_not_query
42
42
 
43
43
  def initialize(index, decl_props, query, params={})
44
44
  @index = index
@@ -156,9 +156,33 @@ module Neo4j
156
156
  # Person.find(:name=>'kalle').and(:age => 3)
157
157
  #
158
158
  def and(query2)
159
- new_query = LuceneQuery.new(@index, @decl_props, query2)
160
- new_query.left_and_query = self
161
- new_query
159
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.left_and_query = self }
160
+ end
161
+
162
+ # Create an OR lucene query.
163
+ #
164
+ # ==== Parameters
165
+ # query2 :: the query that should be OR together
166
+ #
167
+ # ==== Example
168
+ #
169
+ # Person.find(:name=>'kalle').or(:age => 3)
170
+ #
171
+ def or(query2)
172
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.left_or_query = self }
173
+ end
174
+
175
+ # Create a NOT lucene query.
176
+ #
177
+ # ==== Parameters
178
+ # query2 :: the query that should exclude matching results
179
+ #
180
+ # ==== Example
181
+ #
182
+ # Person.find(:age => 3).not(:name=>'kalle')
183
+ #
184
+ def not(query2)
185
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.right_not_query = self }
162
186
  end
163
187
 
164
188
 
@@ -175,11 +199,26 @@ module Neo4j
175
199
  end
176
200
 
177
201
  def build_and_query(query) #:nodoc:
178
- left_query = @left_and_query.build_query
179
- and_query = org.apache.lucene.search.BooleanQuery.new
180
- and_query.add(left_query, org.apache.lucene.search.BooleanClause::Occur::MUST)
181
- and_query.add(query, org.apache.lucene.search.BooleanClause::Occur::MUST)
182
- and_query
202
+ build_composite_query(@left_and_query.build_query, query, org.apache.lucene.search.BooleanClause::Occur::MUST)
203
+ end
204
+
205
+ def build_or_query(query) #:nodoc:
206
+ build_composite_query(@left_or_query.build_query, query, org.apache.lucene.search.BooleanClause::Occur::SHOULD)
207
+ end
208
+
209
+ def build_not_query(query) #:nodoc:
210
+ right_query = @right_not_query.build_query
211
+ composite_query = org.apache.lucene.search.BooleanQuery.new
212
+ composite_query.add(query, org.apache.lucene.search.BooleanClause::Occur::MUST_NOT)
213
+ composite_query.add(right_query, org.apache.lucene.search.BooleanClause::Occur::MUST)
214
+ composite_query
215
+ end
216
+
217
+ def build_composite_query(left_query, right_query, opeartor) #:nodoc:
218
+ composite_query = org.apache.lucene.search.BooleanQuery.new
219
+ composite_query.add(left_query, opeartor)
220
+ composite_query.add(right_query, opeartor)
221
+ composite_query
183
222
  end
184
223
 
185
224
  def build_sort_query(query) #:nodoc:
@@ -224,6 +263,8 @@ module Neo4j
224
263
  query = @query
225
264
  query = build_hash_query(query) if Hash === query
226
265
  query = build_and_query(query) if @left_and_query
266
+ query = build_or_query(query) if @left_or_query
267
+ query = build_not_query(query) if @right_not_query
227
268
  query = build_sort_query(query) if @order
228
269
  query
229
270
  end
@@ -0,0 +1,66 @@
1
+ module Neo4j::Rails
2
+ # Allows accepting id for association objjects. For example
3
+ # class Book < Neo4j::Model
4
+ # has_one(:author).to(Author)
5
+ # accepts_id_for :author
6
+ # end
7
+ #
8
+ # This would add a author_id getter and setter on Book. You could use
9
+ # book = Book.new(:name => 'Graph DBs', :author_id => 11)
10
+ # book.author_id # 11
11
+ # book.author_id = 13
12
+ # TODO: Support for has_n associations
13
+ module AcceptId
14
+ extend ActiveSupport::Concern
15
+
16
+ module ClassMethods
17
+ # Adds association_id getter and setter for one or more has_one associations
18
+ #
19
+ # @example
20
+ # class Book < Neo4j::Model
21
+ # has_one(:author).to(Author)
22
+ # has_one(:publisher).to(Publisher)
23
+ # accepts_id_for :author, :publisher
24
+ # end
25
+ def accepts_id_for(*association_names)
26
+ association_names.each do |association_name|
27
+ define_association_id_getter(association_name)
28
+ define_association_id_setter(association_name)
29
+ accepts_id_associations << association_name
30
+ end
31
+ end
32
+
33
+ # Check if model accepsts id for its association
34
+ # @example
35
+ # Book.accepts_id_for?(:author) => true
36
+ # Book.accepts_id_for?(:genre) => false
37
+ def accepts_id_for?(association_name)
38
+ accepts_id_associations.include?(association_name)
39
+ end
40
+
41
+ def accepts_id_associations #nodoc
42
+ @accepts_id_associations ||= []
43
+ end
44
+
45
+ protected
46
+ def define_association_id_getter(association_name)
47
+ class_eval %Q{
48
+ def #{association_name}_id
49
+ association_object = self.#{association_name}
50
+ association_object.present? ? association_object.id : nil
51
+ end
52
+ }, __FILE__, __LINE__
53
+ end
54
+
55
+ def define_association_id_setter(association_name)
56
+ class_eval %Q{
57
+ def #{association_name}_id=(id)
58
+ relation_target_class = self.class._decl_rels[:#{association_name}].target_class
59
+ association_class = relation_target_class <= self.class ? Neo4j::Model : relation_target_class
60
+ self.#{association_name} = id.present? ? association_class.find(id) : nil
61
+ end
62
+ }, __FILE__, __LINE__
63
+ end
64
+ end
65
+ end
66
+ end
@@ -55,8 +55,7 @@ module Neo4j
55
55
  def #{rel_type}=(other)
56
56
  dsl = _decl_rels_for(:'#{rel_type}')
57
57
  storage = _create_or_get_storage_for_decl_rels(dsl)
58
- rel = storage.single_relationship(dsl.dir)
59
- rel && rel.destroy
58
+ storage.destroy_single_relationship(dsl.dir)
60
59
  storage.create_relationship_to(other, dsl.dir)
61
60
  end
62
61
  RUBY
@@ -270,6 +270,7 @@ module Neo4j
270
270
  include Finders # ActiveRecord style find
271
271
  include Relationships # for none persisted relationships
272
272
  include Compositions
273
+ include AcceptId
273
274
  end
274
275
  end
275
276
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/class/attribute_accessors'
2
+
1
3
  module Neo4j
2
4
  module Rails
3
5
  # Observer classes respond to life cycle callbacks to implement trigger-like
@@ -86,11 +88,26 @@ module Neo4j
86
88
  # In order to activate an observer, list it in the +config.neo4j.observers+
87
89
  # configuration setting in your +config/application.rb+ file.
88
90
  #
89
- # config.neo4j.observers = :comment_observer, :signup_observer
91
+ # config.neo4j.observers = [:comment_observer, :signup_observer]
90
92
  #
91
93
  # Observers will not be invoked unless you define them in your
92
94
  # application configuration.
93
95
  #
96
+ # During testing you may want (and probably should) to disable all the observers.
97
+ # Most of the time you don't want any kind of emails to be sent when creating objects.
98
+ # This should improve the speed of your tests and isolate the models and observer logic.
99
+ #
100
+ # For example, the following will disable the observers in RSpec:
101
+ #
102
+ # config.before(:each) { Neo4j::Rails::Observer.disable_observers }
103
+ #
104
+ # But if you do want to run a particular observer(s) as part of the test,
105
+ # you can temporarily enable it:
106
+ #
107
+ # Neo4j::Rails::Observer.with_observers(:user_recorder, :account_observer) do
108
+ # # Any code here will work with observers enabled
109
+ # end
110
+ #
94
111
  # == Loading
95
112
  #
96
113
  # Observers register themselves with the model class that they observe,
@@ -113,6 +130,48 @@ module Neo4j
113
130
  super and observed_descendants.each { |klass| add_observer!(klass) }
114
131
  end
115
132
 
133
+ cattr_accessor :default_observers_enabled, :observers_enabled
134
+
135
+ # TODO: Add docs
136
+ class << self
137
+ # Enables all observers (default behavior)
138
+ def enable_observers
139
+ self.default_observers_enabled = true
140
+ end
141
+
142
+ # Disables all observers
143
+ def disable_observers
144
+ self.default_observers_enabled = false
145
+ end
146
+
147
+ # Run a block with a specific set of observers enabled
148
+ def with_observers(*observer_syms)
149
+ self.observers_enabled = Array(observer_syms).map do |o|
150
+ o.respond_to?(:instance) ? o.instance : o.to_s.classify.constantize.instance
151
+ end
152
+ yield
153
+ ensure
154
+ self.observers_enabled = []
155
+ end
156
+
157
+ # Determines whether an observer is enabled. Either:
158
+ # - All observers are enabled OR
159
+ # - The observer is in the whitelist
160
+ def observer_enabled?(observer)
161
+ default_observers_enabled or self.observers_enabled.include?(observer)
162
+ end
163
+ end
164
+
165
+
166
+ # Determines whether this observer should be run
167
+ def observer_enabled?
168
+ self.class.observer_enabled?(self)
169
+ end
170
+
171
+ # By default, enable all observers
172
+ enable_observers
173
+ self.observers_enabled = []
174
+
116
175
  protected
117
176
 
118
177
  # Get all the child observers.
@@ -149,7 +208,7 @@ module Neo4j
149
208
  callback_meth = :"_notify_#{observer_name}_for_#{callback}"
150
209
  unless klass.respond_to?(callback_meth)
151
210
  klass.send(:define_method, callback_meth) do |&block|
152
- observer.send(callback, self, &block)
211
+ observer.send(callback, self, &block) if observer.observer_enabled?
153
212
  end
154
213
  klass.send(callback, callback_meth)
155
214
  end
@@ -190,7 +190,7 @@ module Neo4j
190
190
  # Ensure any defaults are stored in the DB
191
191
  def write_default_attributes
192
192
  attribute_defaults.each do |attribute, value|
193
- write_attribute(attribute, Neo4j::TypeConverters.convert(value, attribute, self.class)) unless changed_attributes.has_key?(attribute) || _java_node.has_property?(attribute)
193
+ write_attribute(attribute, Neo4j::TypeConverters.convert(value, attribute, self.class, false)) unless changed_attributes.has_key?(attribute) || _java_node.has_property?(attribute)
194
194
  end
195
195
  end
196
196
 
@@ -11,6 +11,7 @@ require 'neo4j/rails/validations'
11
11
  require 'neo4j/rails/callbacks'
12
12
  require 'neo4j/rails/observer'
13
13
  require 'neo4j/rails/compositions'
14
+ require 'neo4j/rails/accept_id'
14
15
  require 'neo4j/rails/timestamps'
15
16
  require 'neo4j/rails/serialization'
16
17
  require 'neo4j/rails/attributes'
@@ -151,16 +151,19 @@ module Neo4j
151
151
  def create()
152
152
  begin
153
153
  # prevent calling create twice
154
- @start_node.rm_outgoing_rel(type, self)
155
- @end_node.rm_incoming_rel(type, self)
154
+ @start_node.add_unpersisted_outgoing_rel(type, self)
155
+ @end_node.add_unpersisted_incoming_rel(type, self)
156
156
 
157
- _persist_start_node
158
- _persist_end_node
157
+ return unless _persist_start_node && _persist_end_node
159
158
 
160
159
  @_java_rel = Neo4j::Relationship.new(type, start_node, end_node)
161
160
  Neo4j::IdentityMap.add(@_java_rel, self)
162
161
  init_on_create
163
162
  clear_changes
163
+
164
+ @start_node.rm_unpersisted_outgoing_rel(type, self)
165
+ @end_node.rm_unpersisted_incoming_rel(type, self)
166
+
164
167
  end unless @end_node.nil? or @start_node.nil?
165
168
  true
166
169
  end
@@ -170,18 +173,14 @@ module Neo4j
170
173
  end
171
174
 
172
175
  def _persist_start_node
173
- unless @start_node.persisted? || @start_node.save
174
- # not sure if this can happen - probably a bug
175
- raise "Can't save start_node #{@start_node} id #{@start_node.id}"
176
- end
176
+ (!@start_node.persisted? || @start_node.relationships_changed?) ? @start_node.save : true
177
177
  end
178
178
 
179
179
  def _persist_end_node
180
- unless @end_node.persisted? || @end_node.save
181
- raise "Can't save end_node #{@end_node} id #{@end_node.id}"
182
- end
180
+ (!@end_node.persisted? || @end_node.relationships_changed?) ? @end_node.save : true
183
181
  end
184
182
 
183
+
185
184
  def init_on_create(*)
186
185
  #self["_classname"] = self.class.to_s
187
186
  write_default_attributes
@@ -185,7 +185,11 @@ module Neo4j
185
185
  def to_s
186
186
  "Node dir: #{@dir}, #{@storage}"
187
187
  end
188
-
188
+
189
+ def rel_changed?
190
+ @storage.persisted?
191
+ end
192
+
189
193
  protected
190
194
 
191
195
 
@@ -30,6 +30,9 @@ module Neo4j
30
30
  @_relationships[decl_rels.rel_type.to_sym] ||= Storage.new(self, decl_rels.rel_type, decl_rels)
31
31
  end
32
32
 
33
+ def _storage_for(rel_type) #:nodoc:
34
+ @_relationships[rel_type.to_sym]
35
+ end
33
36
 
34
37
  # If the node is persisted and it does not have any unsaved relationship it returns a Neo4j::NodeTraverser.
35
38
  # Otherwise it will return a NodesDSL which behaves like the Neo4j::NodeTraverser except that it does not
@@ -90,6 +93,37 @@ module Neo4j
90
93
  _create_or_get_storage(rel_type).rm_outgoing_rel(rel)
91
94
  end
92
95
 
96
+ def rm_outgoing_rel(rel_type, rel) #:nodoc:
97
+ _create_or_get_storage(rel_type).rm_outgoing_rel(rel)
98
+ end
99
+
100
+ def add_unpersisted_incoming_rel(rel_type, rel) #:nodoc
101
+ storage = _storage_for(rel_type)
102
+ # move the relationship since we are now about to store the relationship
103
+ storage.add_unpersisted_incoming_rel(rel)
104
+ storage.rm_incoming_rel(rel)
105
+ end
106
+
107
+ def add_unpersisted_outgoing_rel(rel_type, rel) #:nodoc
108
+ storage = _storage_for(rel_type)
109
+ # move the relationship since we are now about to store the relationship
110
+ storage.add_unpersisted_outgoing_rel(rel)
111
+ storage.rm_outgoing_rel(rel)
112
+ end
113
+
114
+ def rm_unpersisted_outgoing_rel(rel_type, rel) #:nodoc
115
+ if (storage = _storage_for(rel_type))
116
+ storage.rm_unpersisted_outgoing_rel(rel)
117
+ end
118
+ end
119
+
120
+ def rm_unpersisted_incoming_rel(rel_type, rel) #:nodoc
121
+ if (storage = _storage_for(rel_type))
122
+ storage.rm_unpersisted_incoming_rel(rel)
123
+ end
124
+ end
125
+
126
+
93
127
  end
94
128
  end
95
129
  end
@@ -20,17 +20,21 @@ module Neo4j
20
20
  end
21
21
 
22
22
  def to_s #:nodoc:
23
- "Storage #{object_id} node: #{@node.id} rel_type: #{@rel_type} outgoing #{@outgoing_rels.size} incoming #{@incoming_rels.size}"
23
+ "Storage #{object_id} node: #{@node.id} rel_type: #{@rel_type} outgoing #{@outgoing_rels.size}/#{@unpersisted_outgoing_rels && @unpersisted_outgoing_rels.size} incoming #{@incoming_rels.size}/#{@unpersisted_incoming_rels && @unpersisted_incoming_rels.size}"
24
24
  end
25
25
 
26
26
  def clear_unpersisted
27
27
  @outgoing_rels.clear
28
28
  @incoming_rels.clear
29
+ @unpersisted_outgoing_rels = nil
30
+ @unpersisted_incoming_rels = nil
29
31
  end
30
32
 
31
33
  def remove_from_identity_map
32
34
  @outgoing_rels.each {|r| Neo4j::IdentityMap.remove(r._java_rel)}
33
35
  @incoming_rels.each {|r| Neo4j::IdentityMap.remove(r._java_rel)}
36
+ @unpersisted_outgoing_rels = nil
37
+ @unpersisted_incoming_rels = nil
34
38
  end
35
39
 
36
40
  def size(dir)
@@ -57,9 +61,9 @@ module Neo4j
57
61
  def relationships(dir)
58
62
  case dir
59
63
  when :outgoing
60
- @outgoing_rels
64
+ @unpersisted_outgoing_rels || @outgoing_rels
61
65
  when :incoming
62
- @incoming_rels
66
+ @unpersisted_incoming_rels || @incoming_rels
63
67
  when :both
64
68
  @incoming_rels + @outgoing_rels
65
69
  end
@@ -122,6 +126,11 @@ module Neo4j
122
126
  end
123
127
  end
124
128
 
129
+ def destroy_single_relationship(dir)
130
+ rel = single_relationship(dir)
131
+ rel && rel.destroy && relationships(dir).delete(rel)
132
+ end
133
+
125
134
  def all_relationships(dir)
126
135
  Enumerator.new(self, :each_rel, dir)
127
136
  end
@@ -155,6 +164,18 @@ module Neo4j
155
164
  @outgoing_rels << rel
156
165
  end
157
166
 
167
+ # Makes the given relationship available in callbacks
168
+ def add_unpersisted_incoming_rel(rel)
169
+ @unpersisted_incoming_rels ||= []
170
+ @unpersisted_incoming_rels << rel
171
+ end
172
+
173
+ # Makes the given relationship available in callbacks
174
+ def add_unpersisted_outgoing_rel(rel)
175
+ @unpersisted_outgoing_rels ||= []
176
+ @unpersisted_outgoing_rels << rel
177
+ end
178
+
158
179
  def rm_incoming_rel(rel)
159
180
  @incoming_rels.delete(rel)
160
181
  end
@@ -163,6 +184,16 @@ module Neo4j
163
184
  @outgoing_rels.delete(rel)
164
185
  end
165
186
 
187
+ def rm_unpersisted_incoming_rel(rel)
188
+ @unpersisted_incoming_rels.delete(rel)
189
+ @unpersisted_incoming_rels = nil if @unpersisted_incoming_rels.empty?
190
+ end
191
+
192
+ def rm_unpersisted_outgoing_rel(rel)
193
+ @unpersisted_outgoing_rels.delete(rel)
194
+ @unpersisted_outgoing_rels = nil if @unpersisted_outgoing_rels.empty?
195
+ end
196
+
166
197
  def persisted?
167
198
  @outgoing_rels.empty? && @incoming_rels.empty?
168
199
  end
@@ -174,14 +205,12 @@ module Neo4j
174
205
  [@outgoing_rels, @incoming_rels, @persisted_related_nodes, @persisted_node_to_relationships, @persisted_relationships].each{|c| c.clear}
175
206
 
176
207
  out_rels.each do |rel|
177
- rel.end_node.rm_incoming_rel(@rel_type.to_sym, rel) if rel.end_node
178
208
  success = rel.persisted? || rel.save
179
209
  # don't think this can happen - just in case, TODO
180
210
  raise "Can't save outgoing #{rel}, validation errors ? #{rel.errors.inspect}" unless success
181
211
  end
182
212
 
183
213
  in_rels.each do |rel|
184
- rel.start_node.rm_outgoing_rel(@rel_type.to_sym, rel) if rel.start_node
185
214
  success = rel.persisted? || rel.save
186
215
  # don't think this can happen - just in case, TODO
187
216
  raise "Can't save incoming #{rel}, validation errors ? #{rel.errors.inspect}" unless success
@@ -68,6 +68,46 @@ module Neo4j
68
68
  end
69
69
  end
70
70
 
71
+ class SymbolConverter
72
+ class << self
73
+
74
+ def convert?(class_or_symbol)
75
+ :symbol == class_or_symbol || Symbol == class_or_symbol
76
+ end
77
+
78
+ def to_java(value)
79
+ return nil unless value
80
+ value.to_s
81
+ end
82
+
83
+ def to_ruby(value)
84
+ return nil unless value
85
+ value.to_sym
86
+ end
87
+ end
88
+ end
89
+
90
+
91
+ class StringConverter
92
+ class << self
93
+
94
+ def convert?(class_or_symbol)
95
+ [String, :string, :text].include? class_or_symbol
96
+ end
97
+
98
+ def to_java(value)
99
+ return nil unless value
100
+ value.to_s
101
+ end
102
+
103
+ def to_ruby(value)
104
+ return nil unless value
105
+ value.to_s
106
+ end
107
+ end
108
+ end
109
+
110
+
71
111
 
72
112
  class FixnumConverter
73
113
  class << self
@@ -184,7 +224,10 @@ module Neo4j
184
224
  end
185
225
 
186
226
  # Always returns a converter that handles to_ruby or to_java
187
- def converter(type = nil)
227
+ # if +enforce_type+ is set to false then it will raise in case of unknown type
228
+ # otherwise it will return the DevaultConverter.
229
+ def converter(type = nil, enforce_type = true)
230
+ return DefaultConverter unless type
188
231
  @converters ||= begin
189
232
  Neo4j::TypeConverters.constants.find_all do |c|
190
233
  Neo4j::TypeConverters.const_get(c).respond_to?(:convert?)
@@ -192,14 +235,16 @@ module Neo4j
192
235
  Neo4j::TypeConverters.const_get(c)
193
236
  end
194
237
  end
195
- (type && @converters.find { |c| c.convert?(type) }) || DefaultConverter
238
+ found = @converters.find {|c| c.convert?(type) }
239
+ raise "The type #{type.inspect} is unknown. Use one of #{@converters.map{|c| c.name.demodulize.sub('Converter','') }.join(", ")} or create a custom type converter." if !found && enforce_type
240
+ found or DefaultConverter
196
241
  end
197
242
 
198
243
  # Converts the given value to a Java type by using the registered converters.
199
244
  # It just looks at the class of the given value unless an attribute name is given.
200
245
  # It will convert it if there is a converter registered (in Neo4j::Config) for this value.
201
- def convert(value, attribute = nil, klass = nil)
202
- converter(attribute_type(value, attribute, klass)).to_java(value)
246
+ def convert(value, attribute = nil, klass = nil, enforce_type = true)
247
+ converter(attribute_type(value, attribute, klass), enforce_type).to_java(value)
203
248
  end
204
249
 
205
250
  # Converts the given property (key, value) to Java if there is a type converter for given type.
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: neo4j
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.3.0
5
+ version: 1.3.1
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-12-06 00:00:00 Z
13
+ date: 2011-12-14 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: orm_adapter
@@ -137,6 +137,7 @@ files:
137
137
  - lib/neo4j/rails/timestamps.rb
138
138
  - lib/neo4j/rails/callbacks.rb
139
139
  - lib/neo4j/rails/tx_methods.rb
140
+ - lib/neo4j/rails/accept_id.rb
140
141
  - lib/neo4j/rails/rel_persistence.rb
141
142
  - lib/neo4j/rails/finders.rb
142
143
  - lib/neo4j/rails/relationship.rb
@@ -150,29 +151,30 @@ files:
150
151
  - lib/neo4j/rails/validations/associated.rb
151
152
  - lib/neo4j/rails/validations/uniqueness.rb
152
153
  - lib/neo4j/rails/validations/non_nil.rb
153
- - lib/neo4j/jars/core/neo4j-kernel-1.5.jar
154
- - lib/neo4j/jars/core/server-api-1.5.jar
154
+ - lib/neo4j/jars/neo4j-community-1.6.M01.jar
155
+ - lib/neo4j/jars/core/neo4j-graph-matching-1.6.M01.jar
156
+ - lib/neo4j/jars/core/neo4j-community-1.6.M01.jar
157
+ - lib/neo4j/jars/core/neo4j-kernel-1.6.M01.jar
158
+ - lib/neo4j/jars/core/server-api-1.6.M01.jar
155
159
  - lib/neo4j/jars/core/geronimo-jta_1.1_spec-1.1.1.jar
156
- - lib/neo4j/jars/core/neo4j-graph-matching-1.5.jar
157
- - lib/neo4j/jars/core/neo4j-shell-1.5.jar
158
- - lib/neo4j/jars/core/neo4j-lucene-index-1.5.jar
160
+ - lib/neo4j/jars/core/neo4j-lucene-index-1.6.M01.jar
161
+ - lib/neo4j/jars/core/neo4j-jmx-1.6.M01.jar
159
162
  - lib/neo4j/jars/core/scala-library-2.9.0-1.jar
163
+ - lib/neo4j/jars/core/neo4j-cypher-1.6.M01.jar
160
164
  - lib/neo4j/jars/core/lucene-core-3.1.0.jar
161
- - lib/neo4j/jars/core/neo4j-graph-algo-1.5.jar
162
- - lib/neo4j/jars/core/neo4j-udc-1.5.jar
163
- - lib/neo4j/jars/core/neo4j-community-1.5.jar
164
- - lib/neo4j/jars/core/neo4j-cypher-1.5.jar
165
+ - lib/neo4j/jars/core/neo4j-graph-algo-1.6.M01.jar
165
166
  - lib/neo4j/jars/core/org.apache.servicemix.bundles.jline-0.9.94_1.jar
166
- - lib/neo4j/jars/core/neo4j-jmx-1.5.jar
167
- - lib/neo4j/jars/ha/neo4j-ha-1.5.jar
167
+ - lib/neo4j/jars/core/neo4j-shell-1.6.M01.jar
168
+ - lib/neo4j/jars/core/neo4j-udc-1.6.M01.jar
168
169
  - lib/neo4j/jars/ha/slf4j-api-1.6.1.jar
169
- - lib/neo4j/jars/ha/neo4j-management-1.5.jar
170
- - lib/neo4j/jars/ha/neo4j-com-1.5.jar
171
- - lib/neo4j/jars/ha/neo4j-enterprise-1.5.jar
170
+ - lib/neo4j/jars/ha/neo4j-backup-1.6.M01.jar
172
171
  - lib/neo4j/jars/ha/zookeeper-3.3.2.jar
173
172
  - lib/neo4j/jars/ha/org.apache.servicemix.bundles.netty-3.2.5.Final_1.jar
174
173
  - lib/neo4j/jars/ha/log4j-1.2.16.jar
175
- - lib/neo4j/jars/ha/neo4j-backup-1.5.jar
174
+ - lib/neo4j/jars/ha/neo4j-enterprise-1.6.M01.jar
175
+ - lib/neo4j/jars/ha/neo4j-ha-1.6.M01.jar
176
+ - lib/neo4j/jars/ha/neo4j-management-1.6.M01.jar
177
+ - lib/neo4j/jars/ha/neo4j-com-1.6.M01.jar
176
178
  - lib/neo4j/index/indexer.rb
177
179
  - lib/neo4j/index/lucene_query.rb
178
180
  - lib/neo4j/index/indexer_registry.rb
Binary file