neo4j 1.2.6-java → 2.0.0.alpha.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +30 -0
  2. data/CONTRIBUTORS +1 -0
  3. data/Gemfile +16 -4
  4. data/README.rdoc +25 -3
  5. data/bin/neo4j-jars +15 -8
  6. data/bin/neo4j-shell +0 -1
  7. data/bin/neo4j-upgrade +72 -0
  8. data/config/neo4j/config.yml +5 -4
  9. data/lib/neo4j/algo/algo.rb +0 -1
  10. data/lib/neo4j/batch/inserter.rb +5 -0
  11. data/lib/neo4j/database.rb +18 -12
  12. data/lib/neo4j/event_handler.rb +76 -9
  13. data/lib/neo4j/has_list/class_methods.rb +1 -1
  14. data/lib/neo4j/has_list/mapping.rb +13 -33
  15. data/lib/neo4j/has_n/decl_relationship_dsl.rb +17 -13
  16. data/lib/neo4j/has_n/mapping.rb +6 -23
  17. data/lib/neo4j/identity_map.rb +0 -3
  18. data/lib/neo4j/index/class_methods.rb +9 -3
  19. data/lib/neo4j/index/index.rb +2 -1
  20. data/lib/neo4j/index/indexer.rb +3 -2
  21. data/lib/neo4j/index/indexer_registry.rb +1 -1
  22. data/lib/neo4j/index/lucene_query.rb +52 -33
  23. data/lib/neo4j/neo4j.rb +19 -0
  24. data/lib/neo4j/node.rb +42 -36
  25. data/lib/neo4j/node_mixin/node_mixin.rb +9 -5
  26. data/lib/neo4j/paginated.rb +23 -0
  27. data/lib/neo4j/rails/accept_id.rb +66 -0
  28. data/lib/neo4j/rails/attributes.rb +14 -9
  29. data/lib/neo4j/rails/compositions.rb +9 -1
  30. data/lib/neo4j/rails/finders.rb +5 -1
  31. data/lib/neo4j/rails/mapping/property.rb +41 -28
  32. data/lib/neo4j/rails/model.rb +2 -0
  33. data/lib/neo4j/rails/observer.rb +61 -2
  34. data/lib/neo4j/rails/persistence.rb +57 -57
  35. data/lib/neo4j/rails/rails.rb +1 -0
  36. data/lib/neo4j/rails/railtie.rb +4 -1
  37. data/lib/neo4j/rails/rel_persistence.rb +11 -12
  38. data/lib/neo4j/rails/relationship.rb +9 -4
  39. data/lib/neo4j/rails/relationships/node_dsl.rb +15 -5
  40. data/lib/neo4j/rails/relationships/relationships.rb +42 -2
  41. data/lib/neo4j/rails/relationships/rels_dsl.rb +60 -3
  42. data/lib/neo4j/rails/relationships/storage.rb +43 -5
  43. data/lib/neo4j/rails/validations/uniqueness.rb +1 -0
  44. data/lib/neo4j/rails/versioning/versioning.rb +64 -9
  45. data/lib/neo4j/relationship.rb +79 -73
  46. data/lib/neo4j/rule/event_listener.rb +7 -1
  47. data/lib/neo4j/rule/functions/count.rb +6 -0
  48. data/lib/neo4j/rule/rule.rb +20 -5
  49. data/lib/neo4j/rule/rule_node.rb +33 -20
  50. data/lib/neo4j/to_java.rb +5 -0
  51. data/lib/neo4j/traversal/traverser.rb +38 -1
  52. data/lib/neo4j/type_converters/type_converters.rb +56 -5
  53. data/lib/neo4j/version.rb +1 -1
  54. data/lib/neo4j.rb +3 -49
  55. data/neo4j.gemspec +2 -2
  56. metadata +191 -216
  57. data/bin/neo4j-shell~ +0 -108
  58. data/lib/Gemfile~ +0 -3
  59. data/lib/config2.yml~ +0 -86
  60. data/lib/neo4j/jars/core/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  61. data/lib/neo4j/jars/core/lucene-core-3.1.0.jar +0 -0
  62. data/lib/neo4j/jars/core/neo4j-backup-1.4.1.jar +0 -0
  63. data/lib/neo4j/jars/core/neo4j-graph-algo-1.4.1.jar +0 -0
  64. data/lib/neo4j/jars/core/neo4j-index-1.3-1.3.M01.jar +0 -0
  65. data/lib/neo4j/jars/core/neo4j-kernel-1.4.1.jar +0 -0
  66. data/lib/neo4j/jars/core/neo4j-lucene-index-1.4.1.jar +0 -0
  67. data/lib/neo4j/jars/ha/log4j-1.2.16.jar +0 -0
  68. data/lib/neo4j/jars/ha/neo4j-com-1.4.1.jar +0 -0
  69. data/lib/neo4j/jars/ha/neo4j-ha-1.4.1.jar +0 -0
  70. data/lib/neo4j/jars/ha/neo4j-jmx-1.4.1.jar +0 -0
  71. data/lib/neo4j/jars/ha/neo4j-management-1.4.1.jar +0 -0
  72. data/lib/neo4j/jars/ha/neo4j-shell-1.4.1.jar +0 -0
  73. data/lib/neo4j/jars/ha/netty-3.2.1.Final.jar +0 -0
  74. data/lib/neo4j/jars/ha/org.apache.servicemix.bundles.jline-0.9.94_1.jar +0 -0
  75. data/lib/neo4j/jars/ha/zookeeper-3.3.2.jar +0 -0
  76. data/lib/neo4j/paginate.rb +0 -25
  77. data/lib/perf.rb~ +0 -36
  78. data/lib/test.rb~ +0 -2
@@ -34,7 +34,7 @@ module Neo4j
34
34
  class DeclRelationshipDsl
35
35
  include Neo4j::ToJava
36
36
 
37
- attr_reader :target_class, :dir, :rel_type
37
+ attr_reader :target_class, :source_class, :dir, :rel_type
38
38
 
39
39
  def initialize(method_id, has_one, target_class)
40
40
  @dir = :outgoing
@@ -42,6 +42,7 @@ module Neo4j
42
42
  @has_one = has_one
43
43
  @rel_type = method_id
44
44
  @target_class = target_class
45
+ @source_class = target_class
45
46
  end
46
47
 
47
48
  def to_s
@@ -63,7 +64,7 @@ module Neo4j
63
64
  def java_dir
64
65
  dir_to_java(@dir)
65
66
  end
66
-
67
+
67
68
  def each_node(node, &block) #:nodoc:
68
69
  node._java_node.getRelationships(java_rel_type, java_dir).each do |rel|
69
70
  block.call(rel.getOtherNode(node).wrapper)
@@ -141,7 +142,7 @@ module Neo4j
141
142
  if (Class === target)
142
143
  # handle e.g. has_n(:friends).to(class)
143
144
  @target_class = target
144
- @rel_type = "#{@target_class}##{@method_id}"
145
+ @rel_type = "#{@source_class}##{@method_id}"
145
146
  elsif (Symbol === target)
146
147
  # handle e.g. has_n(:friends).to(:knows)
147
148
  @rel_type = target.to_s
@@ -163,7 +164,7 @@ module Neo4j
163
164
  # class FileNode
164
165
  # include Neo4j::NodeMixin
165
166
  # # will only traverse any incoming relationship of type files from node FileNode
166
- # has_one(:folder).from(FileNode, :files)
167
+ # has_one(:folder).from(FolderNode, :files)
167
168
  # end
168
169
  #
169
170
  # file = FileNode.new
@@ -183,7 +184,7 @@ module Neo4j
183
184
  # end
184
185
  #
185
186
  # file = FileNode.new
186
- # # create an outgoing relationship of type 'FileNode#files' from folder node to file
187
+ # # create an outgoing relationship of type 'files' from folder node to file
187
188
  # file.folder = FolderNode.new
188
189
  #
189
190
  #
@@ -192,14 +193,9 @@ module Neo4j
192
193
 
193
194
  if (args.size > 1)
194
195
  # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
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
+ @rel_type = "#{@target_class}##{args[1]}"
198
+ @relationship_name = args[1]
203
199
  elsif (Symbol === args[0])
204
200
  # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
205
201
  @rel_type = args[0]
@@ -235,7 +231,15 @@ module Neo4j
235
231
  end
236
232
 
237
233
  def relationship_class # :nodoc:
238
- @relationship
234
+ if !@relationship_name.nil? && @relationship.nil?
235
+ other_class_dsl = @target_class._decl_rels[@relationship_name]
236
+ if other_class_dsl
237
+ @relationship = other_class_dsl.relationship_class
238
+ else
239
+ Neo4j.logger.warn "Unknown outgoing relationship #{@relationship_name} on #{@target_class}"
240
+ end
241
+ end
242
+ @relationship
239
243
  end
240
244
  end
241
245
  end
@@ -7,7 +7,7 @@ module Neo4j
7
7
 
8
8
  # The object created by a has_n or has_one Neo4j::NodeMixin class method which enables creating and traversal of nodes.
9
9
  #
10
- # Includes the Enumerable and WillPaginate mixins.
10
+ # Includes the Enumerable mixin.
11
11
  # The Neo4j::Mapping::ClassMethods::Relationship#has_n and Neo4j::Mapping::ClassMethods::Relationship#one
12
12
  # methods returns an object of this type.
13
13
  #
@@ -16,8 +16,6 @@ module Neo4j
16
16
  #
17
17
  class Mapping
18
18
  include Enumerable
19
- include WillPaginate::Finders::Base
20
-
21
19
  include ToJava
22
20
 
23
21
  def initialize(node, dsl) # :nodoc:
@@ -30,7 +28,7 @@ module Neo4j
30
28
  end
31
29
 
32
30
  def size
33
- self.to_a.size
31
+ self.to_a.size # TODO: Optimise this
34
32
  end
35
33
 
36
34
  alias_method :length, :size
@@ -50,13 +48,13 @@ module Neo4j
50
48
  end
51
49
 
52
50
  # Required by the Enumerable mixin.
53
- def each(&block)
54
- @dsl.each_node(@node, &block)
51
+ def each
52
+ @dsl.each_node(@node) {|n| yield n} # Should use yield here as passing &block through doesn't always work (why?)
55
53
  end
56
54
 
57
55
  # returns none wrapped nodes, you may get better performance using this method
58
- def _each(&block)
59
- @dsl._each_node(@node, &block)
56
+ def _each
57
+ @dsl._each_node(@node) {|n| yield n}
60
58
  end
61
59
 
62
60
  # Returns an real ruby array.
@@ -64,21 +62,6 @@ module Neo4j
64
62
  self.to_a
65
63
  end
66
64
 
67
- def wp_query(options, pager, args, &block) #:nodoc:
68
- page = pager.current_page || 1
69
- to = pager.per_page * page
70
- from = to - pager.per_page
71
- i = 0
72
- res = []
73
- _each do |node|
74
- res << node.wrapper if i >= from
75
- i += 1
76
- break if i >= to
77
- end
78
- pager.replace res
79
- pager.total_entries ||= self.size # TODO, this could be very slow to do
80
- end
81
-
82
65
  # Returns true if there are no node in this type of relationship
83
66
  def empty?
84
67
  first == nil
@@ -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
@@ -53,13 +53,19 @@ module Neo4j
53
53
  #
54
54
  # Person.index_names[:fulltext] => 'my_location'
55
55
  # Person.index_names[:exact] => 'Foo_Person-exact' # default Location
56
- # Notice in versions <= 1.0.0.beta.29 the default location was 'Foo::Person-exact'
57
- # which does not work on Windows [lighthouse ticket #147]
56
+ #
57
+ # The index can be prefixed, see Neo4j#threadlocal_ref_node= and multi dendency.
58
58
  #
59
59
  # :singleton-method: index_names
60
60
 
61
61
 
62
- def_delegators :@_indexer, :index, :find, :index?, :index_type?, :delete_index_type, :rm_field_type, :add_index, :rm_index, :index_type_for, :index_names
62
+ ##
63
+ # Returns a hash of which indexes has been defined and the type of index (:exact or :fulltext)
64
+ #
65
+ # :singleton-method: index_types
66
+
67
+
68
+ def_delegators :@_indexer, :index, :find, :index?, :index_type?, :delete_index_type, :rm_field_type, :add_index, :rm_index, :index_type_for, :index_names, :index_types
63
69
 
64
70
  # Sets which indexer should be used for the given node class.
65
71
  # You can share an indexer between several different classes.
@@ -19,7 +19,8 @@ module Neo4j
19
19
  # Neo4j::Index::ClassMethods::index
20
20
  #
21
21
  def add_index(field, value=self[field])
22
- self.class.add_index(wrapped_entity, field.to_s, value)
22
+ converted_value = Neo4j::TypeConverters.convert(value, field, self.class)
23
+ self.class.add_index(wrapped_entity, field.to_s, converted_value)
23
24
  end
24
25
 
25
26
  # Removes an index on the given property.
@@ -2,6 +2,7 @@ module Neo4j
2
2
  module Index
3
3
  class Indexer
4
4
  attr_reader :indexer_for, :field_types, :via_relationships, :entity_type, :parent_indexers, :via_relationships
5
+ alias_method :index_types, :field_types # public method accessible from node.index_types
5
6
 
6
7
  def initialize(clazz, type) #:nodoc:
7
8
  # part of the unique name of the index
@@ -155,7 +156,7 @@ module Neo4j
155
156
  end
156
157
 
157
158
  def update_single_index_on(node, field, old_val, new_val) #:nodoc:
158
- if @field_types.include?(field)
159
+ if @field_types.has_key?(field)
159
160
  rm_index(node, field, old_val) if old_val
160
161
  add_index(node, field, new_val) if new_val
161
162
  end
@@ -322,7 +323,7 @@ module Neo4j
322
323
  def index_names
323
324
  @index_names ||= Hash.new do |hash, index_type|
324
325
  default_filename = index_prefix + @indexer_for.to_s.gsub('::', '_')
325
- hash.fetch(index_type) {"#{default_filename}-#{index_type}"}
326
+ hash.fetch(index_type) {"#{default_filename}_#{index_type}"}
326
327
  end
327
328
  end
328
329
 
@@ -10,7 +10,7 @@ module Neo4j
10
10
  def create_for(this_clazz, using_other_clazz, type)
11
11
  @@indexers ||= {}
12
12
  index = Indexer.new(this_clazz, type)
13
- index.inherit_fields_from(@@indexers[using_other_clazz.to_s])
13
+ index.inherit_fields_from(@@indexers[using_other_clazz.to_s]) if @@indexers[using_other_clazz.to_s]
14
14
  @@indexers[this_clazz.to_s] = index
15
15
  end
16
16
 
@@ -37,8 +37,7 @@ module Neo4j
37
37
  #
38
38
  class LuceneQuery
39
39
  include Enumerable
40
- include WillPaginate::Finders::Base
41
- attr_accessor :left_and_query, :left_or_query
40
+ attr_accessor :left_and_query, :left_or_query, :right_not_query
42
41
 
43
42
  def initialize(index, decl_props, query, params={})
44
43
  @index = index
@@ -52,30 +51,9 @@ module Neo4j
52
51
  end
53
52
  end
54
53
 
55
- def wp_query(options, pager, args, &block) #:nodoc:
56
- @params[:page] = pager.current_page
57
- @params[:per_page] = pager.per_page
58
- pager.replace [*self]
59
- pager.total_entries = size
60
- end
61
-
62
- # Since we include the Ruby Enumerable mixin we need this method.
54
+ # Implements the Ruby +Enumerable+ interface
63
55
  def each
64
- if @params.include?(:per_page)
65
- # paginate the result, used by the will_paginate gem
66
- page = @params[:page] || 1
67
- per_page = @params[:per_page]
68
- to = per_page * page
69
- from = to - per_page
70
- i = 0
71
- hits.each do |node|
72
- yield node.wrapper if i >= from
73
- i += 1
74
- break if i >= to
75
- end
76
- else
77
- hits.each { |n| yield n.wrapper }
78
- end
56
+ hits.each { |x| yield x.wrapper }
79
57
  end
80
58
 
81
59
  # Close hits
@@ -156,9 +134,33 @@ module Neo4j
156
134
  # Person.find(:name=>'kalle').and(:age => 3)
157
135
  #
158
136
  def and(query2)
159
- new_query = LuceneQuery.new(@index, @decl_props, query2)
160
- new_query.left_and_query = self
161
- new_query
137
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.left_and_query = self }
138
+ end
139
+
140
+ # Create an OR lucene query.
141
+ #
142
+ # ==== Parameters
143
+ # query2 :: the query that should be OR together
144
+ #
145
+ # ==== Example
146
+ #
147
+ # Person.find(:name=>'kalle').or(:age => 3)
148
+ #
149
+ def or(query2)
150
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.left_or_query = self }
151
+ end
152
+
153
+ # Create a NOT lucene query.
154
+ #
155
+ # ==== Parameters
156
+ # query2 :: the query that should exclude matching results
157
+ #
158
+ # ==== Example
159
+ #
160
+ # Person.find(:age => 3).not(:name=>'kalle')
161
+ #
162
+ def not(query2)
163
+ LuceneQuery.new(@index, @decl_props, query2).tap { |new_query| new_query.right_not_query = self }
162
164
  end
163
165
 
164
166
 
@@ -175,11 +177,26 @@ module Neo4j
175
177
  end
176
178
 
177
179
  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
180
+ build_composite_query(@left_and_query.build_query, query, org.apache.lucene.search.BooleanClause::Occur::MUST)
181
+ end
182
+
183
+ def build_or_query(query) #:nodoc:
184
+ build_composite_query(@left_or_query.build_query, query, org.apache.lucene.search.BooleanClause::Occur::SHOULD)
185
+ end
186
+
187
+ def build_not_query(query) #:nodoc:
188
+ right_query = @right_not_query.build_query
189
+ composite_query = org.apache.lucene.search.BooleanQuery.new
190
+ composite_query.add(query, org.apache.lucene.search.BooleanClause::Occur::MUST_NOT)
191
+ composite_query.add(right_query, org.apache.lucene.search.BooleanClause::Occur::MUST)
192
+ composite_query
193
+ end
194
+
195
+ def build_composite_query(left_query, right_query, opeartor) #:nodoc:
196
+ composite_query = org.apache.lucene.search.BooleanQuery.new
197
+ composite_query.add(left_query, opeartor)
198
+ composite_query.add(right_query, opeartor)
199
+ composite_query
183
200
  end
184
201
 
185
202
  def build_sort_query(query) #:nodoc:
@@ -224,6 +241,8 @@ module Neo4j
224
241
  query = @query
225
242
  query = build_hash_query(query) if Hash === query
226
243
  query = build_and_query(query) if @left_and_query
244
+ query = build_or_query(query) if @left_or_query
245
+ query = build_not_query(query) if @right_not_query
227
246
  query = build_sort_query(query) if @order
228
247
  query
229
248
  end
data/lib/neo4j/neo4j.rb CHANGED
@@ -13,6 +13,9 @@ require 'neo4j/database'
13
13
  #
14
14
  module Neo4j
15
15
 
16
+ # The version of the Neo4j jar files
17
+ NEO_VERSION = Neo4j::Community::VERSION
18
+
16
19
  class << self
17
20
  # Start Neo4j using the default database.
18
21
  # This is usally not required since the database will be started automatically when it is used.
@@ -71,6 +74,22 @@ module Neo4j
71
74
  Neo4j::Config
72
75
  end
73
76
 
77
+ # Executes a Cypher Query
78
+ # Check the neo4j http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html
79
+ # Returns an enumerable of hash values.
80
+ #
81
+ # === Usage
82
+ #
83
+ # q = Neo4j.query("START n=node({node}) RETURN n", 'node' => @node.neo_id)
84
+ # q.first['n'] #=> the @node
85
+ # q.columns.first => 'n'
86
+ #
87
+ def query(query, params = {})
88
+ engine = org.neo4j.cypher.javacompat.ExecutionEngine.new(db)
89
+ engine.execute(query, params)
90
+ end
91
+
92
+
74
93
  # Returns the logger used by neo4j.
75
94
  # If not specified (with Neo4j.logger=) it will use the standard Ruby logger.
76
95
  # You can change standard logger threshold by configuration :logger_level.
data/lib/neo4j/node.rb CHANGED
@@ -7,42 +7,6 @@ require 'neo4j/equal'
7
7
  require 'neo4j/load'
8
8
 
9
9
  module Neo4j
10
-
11
- org.neo4j.kernel.impl.core.NodeProxy.class_eval do
12
- include Neo4j::Property
13
- include Neo4j::Rels
14
- include Neo4j::Traversal
15
- include Neo4j::Equal
16
- include Neo4j::Index
17
-
18
- def del #:nodoc:
19
- rels.each {|r| r.del}
20
- delete
21
- nil
22
- end
23
-
24
- def exist? #:nodoc:
25
- Neo4j::Node.exist?(self)
26
- end
27
-
28
- def wrapped_entity #:nodoc:
29
- self
30
- end
31
-
32
- def wrapper #:nodoc:
33
- self.class.wrapper(self)
34
- end
35
-
36
- def _java_node #:nodoc:
37
- self
38
- end
39
-
40
- def class #:nodoc:
41
- Neo4j::Node
42
- end
43
- end
44
-
45
-
46
10
  # A node in the graph with properties and relationships to other entities.
47
11
  # Along with relationships, nodes are the core building blocks of the Neo4j data representation model.
48
12
  # Node has three major groups of operations: operations that deal with relationships, operations that deal with properties and operations that traverse the node space.
@@ -259,6 +223,48 @@ module Neo4j
259
223
  nil
260
224
  end
261
225
 
226
+ def extend_java_class(java_clazz) #:nodoc:
227
+ java_clazz.class_eval do
228
+ include Neo4j::Property
229
+ include Neo4j::Rels
230
+ include Neo4j::Traversal
231
+ include Neo4j::Equal
232
+ include Neo4j::Index
233
+
234
+ def del #:nodoc:
235
+ rels.each { |r| r.del }
236
+ delete
237
+ nil
238
+ end
239
+
240
+ def exist? #:nodoc:
241
+ Neo4j::Node.exist?(self)
242
+ end
243
+
244
+ def wrapped_entity #:nodoc:
245
+ self
246
+ end
247
+
248
+ def wrapper #:nodoc:
249
+ self.class.wrapper(self)
250
+ end
251
+
252
+ def _java_node #:nodoc:
253
+ self
254
+ end
255
+
256
+ def class #:nodoc:
257
+ Neo4j::Node
258
+ end
259
+ end
260
+ end
262
261
  end
263
262
  end
263
+
264
+ # org.neo4j.kernel.HighlyAvailableGraphDatabase$LookupNode
265
+ #
266
+ Neo4j::Node.extend_java_class(org.neo4j.kernel.impl.core.NodeProxy)
267
+
268
+
269
+
264
270
  end
@@ -36,8 +36,6 @@ module Neo4j
36
36
  # * Neo4j::Index::ClassMethods
37
37
  # * Neo4j::HasList::ClassMethods
38
38
  #
39
- # This class also includes the class mixin WillPaginate::Finders::Base, see http://github.com/mislav/will_paginate/wiki
40
- #
41
39
  module NodeMixin
42
40
  include Neo4j::Index
43
41
 
@@ -80,7 +78,7 @@ module Neo4j
80
78
  def _java_entity
81
79
  @_java_node
82
80
  end
83
-
81
+
84
82
  # Trigger rules.
85
83
  # You don't normally need to call this method (except in Migration) since
86
84
  # it will be triggered automatically by the Neo4j::Rule::Rule
@@ -99,6 +97,13 @@ module Neo4j
99
97
  self
100
98
  end
101
99
 
100
+ def pagination_source(*a)
101
+ binding.pry
102
+ end
103
+
104
+ def self.pagination_source(*a)
105
+ binding.pry
106
+ end
102
107
 
103
108
  def self.included(c) # :nodoc:
104
109
  c.instance_eval do
@@ -119,7 +124,6 @@ module Neo4j
119
124
  c.extend Neo4j::Rule::ClassMethods
120
125
  c.extend Neo4j::HasList::ClassMethods
121
126
  c.extend Neo4j::Index::ClassMethods
122
- c.extend WillPaginate::Finders::Base
123
127
 
124
128
  def c.inherited(subclass)
125
129
  # inherit the index properties
@@ -131,7 +135,7 @@ module Neo4j
131
135
  super
132
136
  end
133
137
 
134
- c.node_indexer c
138
+ c.node_indexer c unless c == Neo4j::Rails::Model
135
139
  end
136
140
  end
137
141
  end
@@ -0,0 +1,23 @@
1
+ module Neo4j
2
+
3
+ # The class provides the pagination based on the given source.
4
+ # The source must be an Enumerable implementing methods drop, first and count (or size).
5
+ # This can be used to paginage any Enumerable collection and
6
+ # provides the integration point for other gems, like will_paginate and kaminari.
7
+ class Paginated
8
+ include Enumerable
9
+ attr_reader :items, :total, :current_page
10
+
11
+ def initialize(items, total, current_page)
12
+ @items, @total, @current_page = items, total, current_page
13
+ end
14
+
15
+ def self.create_from(source, page, per_page)
16
+ partial = source.drop((page-1) * per_page).first(per_page)
17
+ Paginated.new(partial, source.count, page)
18
+ end
19
+
20
+ delegate :each, :to => :items
21
+ delegate :size, :[], :to => :items
22
+ end
23
+ end
@@ -0,0 +1,66 @@
1
+ module Neo4j::Rails
2
+ # Allows accepting id for association objects. 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
@@ -38,7 +38,7 @@ module Neo4j
38
38
  key_s = key.to_s
39
39
  if !@properties.has_key?(key_s) || @properties[key_s] != value
40
40
  attribute_will_change!(key_s)
41
- @properties[key_s] = value
41
+ @properties[key_s] = value.nil? ? attribute_defaults[key_s] : value
42
42
  end
43
43
  value
44
44
  end
@@ -98,16 +98,17 @@ module Neo4j
98
98
  send(name + "=", nil)
99
99
  else
100
100
 
101
- value = if :time == decl_type
101
+ #TODO: Consider extracting hardcoded assignments into "Binders"
102
+ value = if Neo4j::TypeConverters::TimeConverter.convert?(decl_type)
102
103
  instantiate_time_object(name, values)
103
- elsif :date == decl_type
104
+ elsif Neo4j::TypeConverters::DateConverter.convert?(decl_type)
104
105
  begin
105
106
  values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
106
107
  Date.new(*values)
107
108
  rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
108
109
  instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
109
110
  end
110
- elsif :datetime == decl_type
111
+ elsif Neo4j::TypeConverters::DateTimeConverter.convert?(decl_type)
111
112
  DateTime.new(*values)
112
113
  else
113
114
  raise "Unknown type #{decl_type}"
@@ -201,8 +202,8 @@ module Neo4j
201
202
  # Known properties are either in the @properties, the declared
202
203
  # properties or the property keys for the persisted node
203
204
  def property?(name)
204
- @properties.keys.include?(name) ||
205
- self.class._decl_props.map { |k| k.to_s }.include?(name) ||
205
+ @properties.has_key?(name) ||
206
+ self.class._decl_props.has_key?(name) ||
206
207
  begin
207
208
  persisted? && super
208
209
  rescue org.neo4j.graphdb.NotFoundException
@@ -216,9 +217,13 @@ module Neo4j
216
217
  def attribute?(name)
217
218
  name[0] != ?_ && property?(name)
218
219
  end
219
-
220
+
220
221
  def _classname
221
- self[:_classname]
222
+ self.class.to_s
223
+ end
224
+
225
+ def _classname=(value)
226
+ write_local_property_without_type_conversion("_classname",value)
222
227
  end
223
228
 
224
229
  # To get ActiveModel::Dirty to work, we need to be able to call undeclared
@@ -248,7 +253,7 @@ module Neo4j
248
253
 
249
254
  # Wrap the setter in a conversion from Ruby to Java
250
255
  def write_local_property_with_type_conversion(property, value)
251
- self.send("#{property}_before_type_cast=", value) if respond_to?("#{property}_before_type_cast=")
256
+ @properties_before_type_cast[property.to_sym]=value if self.class._decl_props.has_key? property.to_sym
252
257
  write_local_property_without_type_conversion(property, Neo4j::TypeConverters.to_java(self.class, property, value))
253
258
  end
254
259
  end