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,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