neo4j 2.0.0.alpha.5-java → 2.0.0.alpha.6-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 (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,110 +0,0 @@
1
- require 'neo4j/rels/traverser'
2
-
3
-
4
- module Neo4j
5
-
6
- # Contains methods for traversing relationship object of depth one from one node.
7
- module Rels
8
- include ToJava
9
-
10
- # Returns the only node of a given type and direction that is attached to this node, or nil.
11
- # This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or one relationships of a given type and direction to another node.
12
- # Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships exist, it is a fatal error that should generate an exception.
13
-
14
- # This method reflects that semantics and returns either:
15
- # * nil if there are zero relationships of the given type and direction,
16
- # * the relationship if there's exactly one, or
17
- # * throws an unchecked exception in all other cases.
18
- #
19
- # This method should be used only in situations with an invariant as described above. In those situations, a "state-checking" method (e.g. #rel?) is not required,
20
- # because this method behaves correctly "out of the box."
21
- #
22
- # Does return the Ruby wrapper object (if it has a '_classname' property) unlike the #_node version of this method
23
- #
24
- def node(dir, type)
25
- n = _node(dir, type)
26
- n && n.wrapper
27
- end
28
-
29
- # Same as #node but instead returns an unwrapped native java node instead
30
- def _node(dir, type)
31
- r = _rel(dir, type)
32
- r && r._other_node(self._java_node)
33
- end
34
-
35
- # Returns an enumeration of relationship objects.
36
- # It always returns relationship of depth one.
37
- #
38
- # See Neo4j::Relationship
39
- #
40
- # ==== Examples
41
- # # Return both incoming and outgoing relationships
42
- # me.rels(:friends, :work).each {|relationship|...}
43
- #
44
- # # Only return outgoing relationship of given type
45
- # me.rels(:friends).outgoing.first.end_node # => my friend node
46
- #
47
- def rels(*type)
48
- Traverser.new(self, type, :both)
49
- end
50
-
51
-
52
- # Returns the only relationship of a given type and direction that is attached to this node, or null.
53
- # This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or
54
- # one relationships of a given type and direction to another node.
55
- # Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships
56
- # exist, it is a fatal error that should generate an unchecked exception. This method reflects that semantics and
57
- # returns either:
58
- #
59
- # * nil if there are zero relationships of the given type and direction,
60
- # * the relationship if there's exactly one, or
61
- # * raise an exception in all other cases.
62
- def rel(dir, type)
63
- result = _rel(dir, type)
64
- result && result.wrapper
65
- end
66
-
67
- # Same as rel but does not return a ruby wrapped object but instead returns the Java object.
68
- def _rel(dir, type)
69
- get_single_relationship(type_to_java(type), dir_to_java(dir))
70
- end
71
-
72
- # Returns the raw java neo4j relationship object.
73
- def _rels(dir=:both, *types)
74
- if types.size > 1
75
- java_types = types.inject([]) { |result, type| result << type_to_java(type) }.to_java(:'org.neo4j.graphdb.RelationshipType')
76
- get_relationships(java_types)
77
- elsif types.size == 1
78
- get_relationships(type_to_java(types[0]), dir_to_java(dir))
79
- elsif dir == :both
80
- get_relationships(dir_to_java(dir))
81
- else
82
- raise "illegal argument, does not accept #{dir} #{types.join(',')} - only dir=:both for any relationship types"
83
- end
84
- end
85
-
86
- # Check if the given relationship exists
87
- # Returns true if there are one or more relationships from this node to other nodes
88
- # with the given relationship.
89
- #
90
- # ==== Parameters
91
- # type:: the key and value to be set, default any type
92
- # dir:: optional default :both (either, :outgoing, :incoming, :both)
93
- #
94
- # ==== Returns
95
- # true if one or more relationships exists for the given type and dir
96
- # otherwise false
97
- #
98
- def rel? (type=nil, dir=:both)
99
- if type
100
- hasRelationship(type_to_java(type), dir_to_java(dir))
101
- else
102
- hasRelationship
103
- end
104
- end
105
-
106
- end
107
-
108
- end
109
-
110
-
@@ -1,102 +0,0 @@
1
- # external neo4j dependencies
2
- require 'neo4j/to_java'
3
-
4
-
5
- module Neo4j
6
- module Rels
7
-
8
- # Traverse relationships of depth one from one node.
9
- # This object is returned when using the Neo4j::Rels which is included in the Neo4j::Node class.
10
- #
11
- class Traverser
12
- include Enumerable
13
- include ToJava
14
-
15
- def initialize(node, types, dir)
16
- @node = node
17
- if types.size > 1
18
- @types = types.inject([]) { |result, type| result << type_to_java(type) }.to_java(:'org.neo4j.graphdb.RelationshipType')
19
- elsif types.size == 1
20
- @type = type_to_java(types[0])
21
- end
22
- @dir = dir
23
- end
24
-
25
- def to_s
26
- if @type
27
- "#{self.class} [type: #{@type} dir:#{@dir}]"
28
- elsif @types
29
- "#{self.class} [types: #{@types.join(',')} dir:#{@dir}]"
30
- else
31
- "#{self.class} [types: ANY dir:#{@dir}]"
32
- end
33
- end
34
-
35
- def each
36
- iter = iterator
37
- while (iter.hasNext())
38
- rel = iter.next
39
- yield rel.wrapper if match_to_other?(rel)
40
- end
41
- end
42
-
43
- def empty?
44
- first == nil
45
- end
46
-
47
- def iterator
48
- if @types
49
- @node.get_relationships(@types).iterator
50
- elsif @type
51
- @node.get_relationships(@type, dir_to_java(@dir)).iterator
52
- else
53
- @node.get_relationships(dir_to_java(@dir)).iterator
54
- end
55
- end
56
-
57
- def match_to_other?(rel)
58
- if @to_other.nil?
59
- true
60
- elsif @dir == :outgoing
61
- rel._end_node == @to_other
62
- elsif @dir == :incoming
63
- rel._start_node == @to_other
64
- else
65
- rel._start_node == @to_other || rel._end_node == @to_other
66
- end
67
- end
68
-
69
- def to_other(to_other)
70
- @to_other = to_other
71
- self
72
- end
73
-
74
- def del
75
- each { |rel| rel.del }
76
- end
77
-
78
- def size
79
- [*self].size
80
- end
81
-
82
- def both
83
- @dir = :both
84
- self
85
- end
86
-
87
- def incoming
88
- raise "Not allowed calling incoming when finding several relationships types" if @types
89
- @dir = :incoming
90
- self
91
- end
92
-
93
- def outgoing
94
- raise "Not allowed calling outgoing when finding several relationships types" if @types
95
- @dir = :outgoing
96
- self
97
- end
98
-
99
- end
100
-
101
- end
102
- end
@@ -1,201 +0,0 @@
1
- module Neo4j
2
- module Rule
3
-
4
-
5
- # Allows you to group nodes by providing a rule.
6
- #
7
- # === Example, finding all nodes of a certain class
8
- # Just add a rule without a code block, then all nodes of that class will be grouped under the given key (<tt>all</tt>
9
- # for the example below).
10
- #
11
- # class Person
12
- # include Neo4j::NodeMixin
13
- # rule :all
14
- # end
15
- #
16
- # Then you can get all the nodes of type Person (and siblings) by
17
- # Person.all.each {|x| ...}
18
- #
19
- # === Example, finding all nodes with a given condition on a property
20
- #
21
- # class Person
22
- # include Neo4j::NodeMixin
23
- # property :age
24
- # rule(:old) { age > 10 }
25
- # end
26
- #
27
- # Now we can find all nodes with a property <tt>age</tt> above 10.
28
- #
29
- # === Chain Rules
30
- #
31
- # class NewsStory
32
- # include Neo4j::NodeMixin
33
- # has_n :readers
34
- # rule(:featured) { |node| node[:featured] == true }
35
- # rule(:young_readers) { !readers.find{|user| !user.young?}}
36
- # end
37
- #
38
- # You can combine two rules. Let say you want to find all stories which are featured and has young readers:
39
- # NewsStory.featured.young_readers.each {...}
40
- #
41
- # === Trigger Other Rules
42
- # You can let one rule trigger another rule.
43
- # Let say you have readers of some magazine and want to know if the magazine has old or young readers.
44
- # So when a reader change from young to old you want to trigger all the magazine that he reads (a but stupid example)
45
- #
46
- # Example
47
- # class Reader
48
- # include Neo4j::NodeMixin
49
- # property :age
50
- # rule(:young, :triggers => :readers) { age < 15 }
51
- # end
52
- #
53
- # class NewsStory
54
- # include Neo4j::NodeMixin
55
- # has_n :readers
56
- # rule(:young_readers) { !readers.find{|user| !user.young?}}
57
- # end
58
- #
59
- # === Performance Considerations
60
- # If you have many rules and many updates this can be a bit slow.
61
- # In order to speed it up somewhat you can use the raw java node object instead by providing an argument in your block.
62
- #
63
- # Example:
64
- #
65
- # class Person
66
- # include Neo4j::NodeMixin
67
- # property :age
68
- # rule(:old) {|node| node[:age] > 10 }
69
- # end
70
- #
71
- # === Thread Safe ?
72
- # Yes, since operations are performed in an transaction. However you may get a deadlock exception:
73
- # http://docs.neo4j.org/html/snapshot/#_deadlocks
74
- #
75
- module ClassMethods
76
-
77
- # Creates an rule node attached to the Neo4j.ref_node
78
- # Can be used to rule all instances of a specific Ruby class.
79
- #
80
- # Example of usage:
81
- # class Person
82
- # include Neo4j::NodeMixin
83
- # property :age
84
- # rule :all
85
- # rule :young { self[:age] < 10 }
86
- # rule(:old, :functions => [Sum.new[:age]) { age > 20 }
87
- # end
88
- #
89
- # p1 = Person.new :age => 5
90
- # p2 = Person.new :age => 7
91
- # p3 = Person.new :age => 12
92
- # Neo4j::Transaction.finish
93
- # Person.all # => [p1,p2,p3]
94
- # Person.young # => [p1,p2]
95
- # p1.young? # => true
96
- # p1.sum(old, :age) # the some of the old people's age
97
- #
98
- def rule(rule_name, props = {}, &block)
99
- singleton = class << self;
100
- self;
101
- end
102
-
103
- # define class methods
104
- singleton.send(:define_method, rule_name) do
105
- rule_node = Rule.rule_node_for(self)
106
- rule_node.traversal(rule_name)
107
- end unless respond_to?(rule_name)
108
-
109
- # define instance methods
110
- self.send(:define_method, "#{rule_name}?") do
111
- instance_eval &block
112
- end
113
-
114
- rule = Rule.add(self, rule_name, props, &block)
115
-
116
- rule.functions && rule.functions.each do |func|
117
- singleton.send(:define_method, func.class.function_name) do |r_name, *args|
118
- rule_node = Rule.rule_node_for(self)
119
- function_id = args.empty? ? "_classname" : args[0]
120
- function = rule_node.find_function(r_name, func.class.function_name, function_id)
121
- function.value(rule_node.rule_node, r_name)
122
- end unless respond_to?(func.class.function_name)
123
- end
124
- end
125
-
126
- def ref_node_for_class
127
- Neo4j.ref_node #The reference node for a type falls back to the threadlocal ref node by default.
128
- end
129
-
130
- # Assigns the reference node for a class via a supplied block.
131
- # Example of usage:
132
- # class Person
133
- # include Neo4j::NodeMixin
134
- # ref_node { Neo4j.default_ref_node }
135
- # end
136
- #
137
- def ref_node(&block)
138
- singleton = class << self;
139
- self;
140
- end
141
- singleton.send(:define_method, :ref_node_for_class) { block.call }
142
- end
143
-
144
- def inherit_rules_from(clazz)
145
- Rule.inherit(clazz, self)
146
- end
147
-
148
- # This is typically used for RSpecs to clean up rule nodes created by the #rule method.
149
- # It also remove all the rule class methods.
150
- def delete_rules
151
- singelton = class << self;
152
- self;
153
- end
154
- rule_node = Rule.rule_node_for(self)
155
-
156
- rule_node.rule_names.each {|rule_name| singelton.send(:remove_method, rule_name)}
157
- rule_node.rules.clear
158
- end
159
-
160
- # Force to trigger the rules.
161
- # You don't normally need that since it will be done automatically.
162
- # This can be useful if you need to trigger rules on already existing nodes in the database.
163
- # Can also be called from an migration.
164
- #
165
- def trigger_rules(node, *changes)
166
- Rule.trigger_rules(node, *changes)
167
- end
168
-
169
- # Returns a proc that will call add method on the given function
170
- # Can be used in migration to trigger rules on already existing nodes.
171
- # Parameter function_id is default to '_classname' which means that
172
- # the function 'reacts' on changes on the property '_classname'.
173
- # That property changes only when a node is created or deleted.
174
- # Function using function_id '_classname' is typically used for counting number of nodes of a class.
175
- def add_function_for(rule_name, function_name_or_class, function_id = '_classname')
176
- function_for(:add, rule_name, function_name_or_class, function_id)
177
- end
178
-
179
- # See #add_function_for
180
- # Calls the delete method on the function.
181
- def delete_function_for(rule_name, function_name_or_class, function_id = '_classname')
182
- function_for(:delete, rule_name, function_name_or_class, function_id)
183
- end
184
-
185
- # Returns a proc that calls the given method on the given function.
186
- def function_for(method, rule_name, function_name_or_class, function_id = '_classname')
187
- function_name = function_name_or_class.is_a?(Symbol)? function_name_or_class : function_name_or_class.function_name
188
- rule_node = Rule.rule_node_for(self)
189
- rule = rule_node.find_rule(rule_name)
190
- rule_node_raw = rule_node.rule_node
191
-
192
- function = rule_node.find_function(rule_name, function_name, function_id)
193
- lambda do |node|
194
- new_value = node[function_id]
195
- function.send(method, rule.rule_name, rule_node_raw, new_value)
196
- end
197
- end
198
- end
199
-
200
- end
201
- end
@@ -1,66 +0,0 @@
1
- module Neo4j
2
- module Rule
3
- class EventListener
4
- class << self
5
- # ----------------------------------------------------------------------------------------------------------------
6
- # Event handling methods
7
- # ----------------------------------------------------------------------------------------------------------------
8
-
9
- def on_relationship_created(rel, *)
10
- trigger_start_node = Rule.trigger?(rel._start_node)
11
- trigger_end_node = Rule.trigger?(rel._end_node)
12
- Rule.trigger_rules(rel._start_node) if trigger_start_node
13
- Rule.trigger_rules(rel._end_node) if trigger_end_node
14
- end
15
-
16
- def on_property_changed(node, *changes)
17
- Rule.trigger_rules(node, *changes) if Rule.trigger?(node)
18
- end
19
-
20
- def on_node_deleted(node, old_properties, deleted_relationship_set, deleted_identity_map)
21
- # have we deleted a rule node ?
22
- del_rule_node = Rule.find_rule_node(node)
23
- del_rule_node && del_rule_node.clear_rule_node
24
- return if del_rule_node
25
-
26
- # do we have prop_aggregations for this
27
- clazz = old_properties['_classname']
28
- rule_node = Rule.rule_node_for(clazz)
29
- return if rule_node.nil?
30
-
31
- id = node.getId
32
- rule_node.rules.each do |rule|
33
- next if rule.functions.nil? || rule.bulk_update?
34
- rule_name = rule.rule_name.to_s
35
-
36
- # is the rule node deleted ?
37
- deleted_rule_node = deleted_identity_map.get(rule_node.rule_node.neo_id)
38
- next if deleted_rule_node
39
-
40
- rule.functions.each do |function|
41
- next unless deleted_relationship_set.contains?(id,rule_name)
42
- previous_value = old_properties[function.function_id]
43
- function.delete(rule_name, rule_node.rule_node, previous_value) if previous_value
44
- end if rule.functions
45
- end
46
- end
47
-
48
- def classes_changed(changed_class_map)
49
- changed_class_map.each_pair do |clazz,class_change|
50
- Rule.bulk_trigger_rules(clazz,class_change,changed_class_map)
51
- end
52
- end
53
-
54
- def on_neo4j_started(db)
55
- if not Neo4j::Config[:enable_rules]
56
- db.event_handler.remove(self)
57
- end
58
- end
59
- end
60
-
61
-
62
- end
63
- Neo4j.unstarted_db.event_handler.add(EventListener) unless Neo4j.read_only?
64
-
65
- end
66
- end