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