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,43 +0,0 @@
1
- module Neo4j
2
- module Rule
3
- module Functions
4
-
5
- # A function for counting number of nodes of a given class.
6
- class Count < Function
7
- def initialize
8
- @property = '_classname'
9
- end
10
-
11
- def calculate?(changed_property)
12
- true
13
- end
14
-
15
- def delete(rule_name, rule_node, old_value)
16
- key = rule_node_property(rule_name)
17
- rule_node[key] ||= 0
18
- rule_node[key] -= 1
19
- end
20
-
21
- def add(rule_name, rule_node, new_value)
22
- key = rule_node_property(rule_name)
23
- rule_node[key] ||= 0
24
- rule_node[key] += 1
25
- end
26
-
27
- def update(*)
28
- # we are only counting, not interested in property changes
29
- end
30
-
31
- def classes_changed(rule_name, rule_node, class_change)
32
- key = rule_node_property(rule_name)
33
- rule_node[key] ||= 0
34
- rule_node[key] += class_change.net_change
35
- end
36
-
37
- def self.function_name
38
- :count
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,74 +0,0 @@
1
- module Neo4j
2
- module Rule
3
- module Functions
4
-
5
- # The base class of rule functions.
6
- #
7
- # You are expected to at least implement two methods:
8
- # * update :: update the rule node value of this function
9
- # * function_name :: the name of this function, the name of the generated method - A class method !
10
- #
11
- class Function
12
-
13
- # Initialize the the function with a property which is usually the same as the function identity.
14
- # See the #calculate? method how this property is used.
15
- #
16
- def initialize(property)
17
- @property = property.to_s
18
- end
19
-
20
- def to_s
21
- "Function #{self.class.function_name} function_id: #{function_id}"
22
- end
23
-
24
- # Decides if the function should be called are not
25
- #
26
- def calculate?(changed_property)
27
- @property == changed_property
28
- end
29
-
30
-
31
- # The identity of the function.
32
- # Used to identify function.
33
- #
34
- # ==== Example
35
- # Person.sum(:young, :age)
36
- #
37
- # In the example above the property :age is the used to identify which function will be called
38
- # since there could be several sum method. In the example we want use the sum method that uses the :age property.
39
- #
40
- def function_id
41
- @property
42
- end
43
-
44
- # The value of the rule
45
- def value(rule_node, rule_name)
46
- key = rule_node_property(rule_name)
47
- rule_node[key] || 0
48
- end
49
-
50
- # Called when a node is removed from a rule group
51
- # Default is calling update method which is expected to be implemented in a subclass
52
- def delete(rule_name, rule_node, old_value)
53
- update(rule_name, rule_node, old_value, nil)
54
- end
55
-
56
- # Called when a node is added to a rule group
57
- # Default is calling update method which is expected to be implemented in a subclass
58
- def add(rule_name, rule_node, new_value)
59
- update(rule_name, rule_node, nil, new_value)
60
- end
61
-
62
- # the name of the property that holds the value of the function
63
- def rule_node_property(rule_name)
64
- self.class.rule_node_property(self.class.function_name, rule_name, @property)
65
- end
66
-
67
- def self.rule_node_property(function_name, rule_name, prop)
68
- "_#{function_name}_#{rule_name}_#{prop}"
69
- end
70
-
71
- end
72
- end
73
- end
74
- end
@@ -1,3 +0,0 @@
1
- require "neo4j/rule/functions/function"
2
- require "neo4j/rule/functions/count"
3
- require "neo4j/rule/functions/sum"
@@ -1,29 +0,0 @@
1
- module Neo4j
2
- module Rule
3
- module Functions
4
-
5
- class Sum < Function
6
- # Updates the function's value.
7
- # Called after the transactions commits and a property has been changed on a node.
8
- #
9
- # ==== Arguments
10
- # * rule_name :: the name of the rule group
11
- # * rule_node :: the node which contains the value of this function
12
- # * old_value new value :: the changed value of the property (when the transaction commits)
13
- def update(rule_name, rule_node, old_value, new_value)
14
- key = rule_node_property(rule_name)
15
- rule_node[key] ||= 0
16
- old_value ||= 0
17
- new_value ||= 0
18
- rule_node[key] += new_value - old_value
19
- end
20
-
21
- def self.function_name
22
- :sum
23
- end
24
- end
25
-
26
-
27
- end
28
- end
29
- end
@@ -1,150 +0,0 @@
1
- require 'neo4j/rule/event_listener'
2
- require 'neo4j/rule/class_methods'
3
- require 'neo4j/rule/rule_node'
4
-
5
- require 'neo4j/rule/functions/functions'
6
-
7
-
8
- module Neo4j
9
- module Rule
10
-
11
-
12
- # Holds all defined rules added by the Neo4j::Rule::ClassMethods#rule method.
13
- #
14
- # See Neo4j::Rule::ClassMethods
15
- #
16
- class Rule
17
-
18
- attr_reader :rule_name, :filter, :triggers, :functions
19
-
20
- def initialize(rule_name, props, &block)
21
- @rule_name = rule_name
22
- @triggers = props[:triggers]
23
- @functions = props[:functions]
24
- @triggers = [@triggers] if @triggers && !@triggers.respond_to?(:each)
25
- @functions = [@functions] if @functions && !@functions.respond_to?(:each)
26
- @filter = block
27
- @bulk_update = !@functions.nil? && @functions.size == 1 && @functions.first.class.function_name == :count && @filter.nil?
28
- end
29
-
30
- def to_s
31
- "Rule #{rule_name} props=#{props.inspect}"
32
- end
33
-
34
- def find_function(function_name, function_id)
35
- function_id = function_id.to_s
36
- @functions && @functions.find { |f| f.function_id == function_id && f.class.function_name == function_name }
37
- end
38
-
39
- # Reconstruct the properties given when created this rule
40
- # Needed when inheriting a rule and we want to duplicate a rule
41
- def props
42
- props = {}
43
- props[:triggers] = @triggers if @triggers
44
- props[:functions] = @functions if @functions
45
- props
46
- end
47
-
48
- def functions_for(property)
49
- @functions && @functions.find_all { |f| f.calculate?(property) }
50
- end
51
-
52
- def execute_filter(node)
53
- if @filter.nil?
54
- true
55
- elsif @filter.arity != 1
56
- node.wrapper.instance_eval(&@filter)
57
- else
58
- @filter.call(node)
59
- end
60
- end
61
-
62
- def bulk_update?
63
- @bulk_update
64
- end
65
-
66
- # ------------------------------------------------------------------------------------------------------------------
67
- # Class Methods
68
- # ------------------------------------------------------------------------------------------------------------------
69
-
70
- @rule_nodes = {}
71
-
72
- class << self
73
-
74
- def add(clazz, rule_name, props, &block)
75
- rule_node = rule_node_for(clazz.to_s)
76
- rule_node.remove_rule(rule_name) # remove any previously inherited rules
77
- rule = Rule.new(rule_name, props, &block)
78
- rule_node.add_rule(rule)
79
- rule
80
- end
81
-
82
- def has_rules?(clazz)
83
- !@rule_nodes[clazz.to_s].nil?
84
- end
85
-
86
- def rule_names_for(clazz)
87
- rule_node = rule_node_for(clazz)
88
- rule_node.rules.map { |rule| rule.rule_name }
89
- end
90
-
91
- def rule_node_for(clazz)
92
- return nil if clazz.nil?
93
- @rule_nodes[clazz.to_s] ||= RuleNode.new(clazz)
94
- end
95
-
96
- def find_rule_node(node)
97
- @rule_nodes && @rule_nodes.values.find { |rn| rn.rule_node?(node) }
98
- end
99
-
100
- def inherit(parent_class, subclass)
101
- # copy all the rules
102
- if rule_node = rule_node_for(parent_class)
103
- rule_node.inherit(subclass)
104
- end
105
- end
106
-
107
- def delete(clazz)
108
- if rule_node = rule_node_for(clazz)
109
- rule_node.delete_node
110
- end
111
- end
112
-
113
- def trigger?(node)
114
- classname = node[:_classname]
115
- @rule_nodes && classname && rule_node_for(classname) && !rule_node_for(classname).bulk_update?
116
- end
117
-
118
- def trigger_rules(node, *changes)
119
- classname = node[:_classname]
120
- return unless classname # there are no rules if there is not a :_classname property
121
- rule_node = rule_node_for(classname)
122
- rule_node.execute_rules(node, *changes)
123
-
124
- # recursively add relationships for all the parent classes with rules that also pass for this node
125
- recursive(node,rule_node.model_class,*changes)
126
- end
127
-
128
- def bulk_trigger_rules(classname,class_change, map)
129
- rule_node = rule_node_for(classname)
130
- rule_node.classes_changed(class_change)
131
- if (clazz = rule_node.model_class.superclass) && clazz.include?(Neo4j::NodeMixin)
132
- bulk_trigger_rules(clazz.name,class_change,map) if clazz != Neo4j::Rails::Model
133
- end
134
- end
135
-
136
- private
137
-
138
- def recursive(node,model_class,*changes)
139
- if (clazz = model_class.superclass) && clazz.include?(Neo4j::NodeMixin)
140
- if clazz != Neo4j::Rails::Model
141
- rule_node = rule_node_for(clazz)
142
- rule_node && rule_node.execute_rules(node, *changes)
143
- recursive(node,clazz,*changes)
144
- end
145
- end
146
- end
147
- end
148
- end
149
- end
150
- end
@@ -1,217 +0,0 @@
1
- module Neo4j
2
- module Rule
3
-
4
- # This is the node that has relationships to all nodes of a given class.
5
- # For example if the PersonNode has a rule then it will also have one RuleNode
6
- # from where it will create relationships to each created node of type PersonNode.
7
- # The RuleNode can also be used to hold properties for functions, like sum and count.
8
- #
9
- class RuleNode
10
- include ToJava
11
- attr_reader :rules
12
- attr_reader :model_class
13
- @@rule_nodes = {}
14
-
15
- def initialize(clazz)
16
- classname = clazz.to_s
17
- @model_class = classname[0,1] == "#" ? eval(classname) : classname.split('::').inject(Kernel) {|sc, const_name| sc.const_get(const_name)}
18
- @classname = clazz
19
- @rules = []
20
- @rule_node_key = ("rule_" + clazz.to_s).to_sym
21
- @ref_node_key = ("rule_ref_for_" + clazz.to_s).to_sym
22
- end
23
-
24
- def to_s
25
- "RuleNode #{@classname}, node #{rule_node} #rules: #{@rules.size}"
26
- end
27
-
28
- # returns true if the rule node exist yet in the database
29
- def node_exist?
30
- !ref_node.rel?(@classname)
31
- end
32
-
33
- def rule_node
34
- ref_node._java_node.synchronized do
35
- @@rule_nodes[key] ||= find_node || create_node
36
- end
37
- end
38
-
39
- def rule_node?(node)
40
- @@rule_nodes[key] == node
41
- end
42
-
43
- def key
44
- "#{ref_node}#{@ref_node_key}".to_sym
45
- end
46
-
47
- def ref_node
48
- if @model_class.respond_to? :ref_node_for_class
49
- @model_class.ref_node_for_class
50
- else
51
- Neo4j.ref_node
52
- end
53
- end
54
-
55
- def create_node
56
- Neo4j::Transaction.run do
57
- node = Neo4j::Node.new
58
- ref_node.create_relationship_to(node, type_to_java(@classname))
59
- node
60
- end
61
- end
62
-
63
- def inherit(subclass)
64
- @rules.each do |rule|
65
- subclass.rule rule.rule_name, rule.props, &rule.filter
66
- end
67
- end
68
-
69
- def delete_node
70
- if ref_node.rel?(@classname)
71
- ref_node.outgoing(@classname).each { |n| n.del }
72
- end
73
- clear_rule_node
74
- end
75
-
76
- def find_node
77
- ref_node.rel?(@classname.to_s) && ref_node._rel(:outgoing, @classname.to_s)._end_node
78
- end
79
-
80
- def ref_node_changed?
81
- if ref_node != Thread.current[@ref_node_key]
82
- Thread.current[@ref_node_key] = ref_node
83
- true
84
- else
85
- false
86
- end
87
- end
88
-
89
- def clear_rule_node
90
- @@rule_nodes[key] = nil
91
- end
92
-
93
- def rule_names
94
- @rules.map { |r| r.rule_name }
95
- end
96
-
97
- def find_rule(rule_name)
98
- @rules.find { |rule| rule.rule_name == rule_name }
99
- end
100
-
101
- def add_rule(rule)
102
- @rules << rule
103
- end
104
-
105
- def remove_rule(rule_name)
106
- r = find_rule(rule_name)
107
- r && @rules.delete(r)
108
- end
109
-
110
- # Return a traversal object with methods for each rule and function.
111
- # E.g. Person.all.old or Person.all.sum(:age)
112
- def traversal(rule_name)
113
- # define method on the traversal
114
- traversal = rule_node.outgoing(rule_name)
115
- @rules.each do |rule|
116
- traversal.filter_method(rule.rule_name) do |path|
117
- path.end_node.rel?(rule.rule_name, :incoming)
118
- end
119
- rule.functions && rule.functions.each do |func|
120
- traversal.functions_method(func, self, rule_name)
121
- end
122
- end
123
- traversal
124
- end
125
-
126
- def find_function(rule_name, function_name, function_id)
127
- rule = find_rule(rule_name)
128
- rule.find_function(function_name, function_id)
129
- end
130
-
131
- def execute_rules(node, *changes)
132
- @rules.each do |rule|
133
- execute_rule(rule, node, *changes)
134
- execute_other_rules(rule, node)
135
- end
136
- end
137
-
138
- def execute_other_rules(rule, node)
139
- rule.triggers && rule.triggers.each do |rel_type|
140
- node.incoming(rel_type).each { |n| n.trigger_rules }
141
- end
142
- end
143
-
144
- def execute_rule(rule, node, *changes)
145
- if rule.execute_filter(node)
146
- if connected?(rule.rule_name, node)
147
- # it was already connected - the node is in the same rule group but a property has changed
148
- execute_update_functions(rule, *changes)
149
- else
150
- # the node has changed or is in a new rule group
151
- connect(rule.rule_name, node)
152
- execute_add_functions(rule, *changes)
153
- end
154
- else
155
- if break_connection(rule.rule_name, node)
156
- # the node has been removed from a rule group
157
- execute_delete_functions(rule, *changes)
158
- end
159
- end
160
- end
161
-
162
- def execute_update_functions(rule, *changes)
163
- if functions = find_functions_for_changes(rule, *changes)
164
- functions && functions.each { |f| f.update(rule.rule_name, rule_node, changes[1], changes[2]) }
165
- end
166
- end
167
-
168
- def execute_add_functions(rule, *changes)
169
- if functions = find_functions_for_changes(rule, *changes)
170
- functions && functions.each { |f| f.add(rule.rule_name, rule_node, changes[2]) }
171
- end
172
- end
173
-
174
- def execute_delete_functions(rule, *changes)
175
- if functions = find_functions_for_changes(rule, *changes)
176
- functions.each { |f| f.delete(rule.rule_name, rule_node, changes[1]) }
177
- end
178
- end
179
-
180
- def find_functions_for_changes(rule, *changes)
181
- !changes.empty? && rule.functions_for(changes[0])
182
- end
183
-
184
- # work out if two nodes are connected by a particular relationship
185
- # uses the end_node to start with because it's more likely to have less relationships to go through
186
- # (just the number of superclasses it has really)
187
- def connected?(rule_name, end_node)
188
- end_node.incoming(rule_name).find { |n| n == rule_node }
189
- end
190
-
191
- def connect(rule_name, end_node)
192
- rule_node._java_node.createRelationshipTo(end_node._java_node, org.neo4j.graphdb.DynamicRelationshipType.withName(rule_name))
193
- end
194
-
195
- # sever a direct one-to-one relationship if it exists
196
- def break_connection(rule_name, end_node)
197
- rel = end_node._rels(:incoming, rule_name).find { |r| r._start_node == rule_node }
198
- rel && rel.del
199
- !rel.nil?
200
- end
201
-
202
- def bulk_update?
203
- @rules.size == 1 && @rules.first.bulk_update?
204
- end
205
-
206
- def classes_changed(total)
207
- @rules.each do |rule|
208
- if rule.bulk_update?
209
- rule.functions.first.classes_changed(rule.rule_name, rule_node, total)
210
- total.added.each{|node| connect(rule.rule_name, node)}
211
- total.deleted.each{|node| break_connection(rule.rule_name, node)}
212
- end
213
- end
214
- end
215
- end
216
- end
217
- end