neo4j 1.0.0.beta.27-java → 1.0.0.beta.28-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/CONTRIBUTORS +1 -0
  2. data/lib/neo4j.rb +38 -72
  3. data/lib/neo4j/{algo.rb → algo/algo.rb} +5 -1
  4. data/lib/neo4j/batch/batch.rb +2 -0
  5. data/lib/neo4j/batch/indexer.rb +108 -0
  6. data/lib/neo4j/batch/inserter.rb +168 -0
  7. data/lib/neo4j/database.rb +13 -8
  8. data/lib/neo4j/{mapping/class_methods/list.rb → has_list/class_methods.rb} +2 -4
  9. data/lib/neo4j/has_list/has_list.rb +3 -0
  10. data/lib/neo4j/{mapping/has_list.rb → has_list/mapping.rb} +2 -2
  11. data/lib/neo4j/{mapping/class_methods/relationship.rb → has_n/class_methods.rb} +42 -12
  12. data/lib/neo4j/has_n/decl_relationship_dsl.rb +216 -0
  13. data/lib/neo4j/has_n/has_n.rb +3 -0
  14. data/lib/neo4j/{mapping/has_n.rb → has_n/mapping.rb} +16 -7
  15. data/lib/neo4j/index/index.rb +5 -0
  16. data/lib/neo4j/index/indexer.rb +27 -22
  17. data/lib/neo4j/index/lucene_query.rb +3 -1
  18. data/lib/neo4j/jars/core/neo4j-graph-algo-0.8-1.3.M01.jar +0 -0
  19. data/lib/neo4j/jars/core/neo4j-index-1.3-1.3.M01.jar +0 -0
  20. data/lib/neo4j/jars/core/neo4j-kernel-1.3-1.3.M01.jar +0 -0
  21. data/lib/neo4j/jars/core/neo4j-lucene-index-0.5-1.3.M01.jar +0 -0
  22. data/lib/neo4j/jars/ha/{neo4j-ha-0.6-SNAPSHOT.jar → neo4j-ha-0.6-1.3.M01.jar} +0 -0
  23. data/lib/neo4j/jars/ha/neo4j-management-1.3-1.3.M01.jar +0 -0
  24. data/lib/neo4j/jars/ha/neo4j-shell-1.3-1.3.M01.jar +0 -0
  25. data/lib/neo4j/migrations/class_methods.rb +102 -0
  26. data/lib/neo4j/migrations/extensions.rb +10 -9
  27. data/lib/neo4j/migrations/lazy_node_mixin.rb +50 -0
  28. data/lib/neo4j/migrations/migration.rb +84 -81
  29. data/lib/neo4j/migrations/migrations.rb +6 -100
  30. data/lib/neo4j/migrations/node_mixin.rb +80 -0
  31. data/lib/neo4j/migrations/ref_node_wrapper.rb +32 -0
  32. data/lib/neo4j/neo4j.rb +11 -0
  33. data/lib/neo4j/node.rb +55 -25
  34. data/lib/neo4j/{mapping/class_methods/init_node.rb → node_mixin/class_methods.rb} +3 -3
  35. data/lib/neo4j/{mapping → node_mixin}/node_mixin.rb +35 -18
  36. data/lib/neo4j/{mapping/class_methods/property.rb → property/class_methods.rb} +5 -4
  37. data/lib/neo4j/{property.rb → property/property.rb} +2 -0
  38. data/lib/neo4j/rails/finders.rb +21 -7
  39. data/lib/neo4j/rails/rails.rb +19 -0
  40. data/lib/neo4j/rails/timestamps.rb +1 -1
  41. data/lib/neo4j/relationship.rb +7 -0
  42. data/lib/neo4j/{mapping/class_methods/init_rel.rb → relationship_mixin/class_methods.rb} +4 -4
  43. data/lib/neo4j/{mapping → relationship_mixin}/relationship_mixin.rb +23 -5
  44. data/lib/neo4j/rels/rels.rb +85 -0
  45. data/lib/neo4j/rels/traverser.rb +102 -0
  46. data/lib/neo4j/{mapping/class_methods/rule.rb → rule/class_methods.rb} +11 -11
  47. data/lib/neo4j/rule/functions/count.rb +37 -0
  48. data/lib/neo4j/rule/functions/function.rb +74 -0
  49. data/lib/neo4j/rule/functions/functions.rb +3 -0
  50. data/lib/neo4j/rule/functions/sum.rb +29 -0
  51. data/lib/neo4j/rule/rule.rb +5 -0
  52. data/lib/neo4j/rule/rule_event_listener.rb +162 -0
  53. data/lib/neo4j/rule/rule_node.rb +182 -0
  54. data/lib/neo4j/to_java.rb +0 -14
  55. data/lib/neo4j/traversal/filter_predicate.rb +25 -0
  56. data/lib/neo4j/traversal/prune_evaluator.rb +14 -0
  57. data/lib/neo4j/traversal/rel_expander.rb +31 -0
  58. data/lib/neo4j/traversal/traversal.rb +90 -0
  59. data/lib/neo4j/traversal/traverser.rb +173 -0
  60. data/lib/neo4j/{type_converters.rb → type_converters/type_converters.rb} +0 -0
  61. data/lib/neo4j/version.rb +1 -1
  62. data/lib/test.rb~ +2 -0
  63. data/neo4j.gemspec +11 -10
  64. metadata +48 -37
  65. data/lib/neo4j/functions/count.rb +0 -33
  66. data/lib/neo4j/functions/function.rb +0 -72
  67. data/lib/neo4j/functions/sum.rb +0 -27
  68. data/lib/neo4j/jars/core/neo4j-graph-algo-0.8-SNAPSHOT.jar +0 -0
  69. data/lib/neo4j/jars/core/neo4j-index-1.3-SNAPSHOT.jar +0 -0
  70. data/lib/neo4j/jars/core/neo4j-kernel-1.3-SNAPSHOT.jar +0 -0
  71. data/lib/neo4j/jars/core/neo4j-lucene-index-0.5-SNAPSHOT.jar +0 -0
  72. data/lib/neo4j/jars/ha/neo4j-management-1.3-SNAPSHOT.jar +0 -0
  73. data/lib/neo4j/jars/ha/neo4j-shell-1.3-SNAPSHOT.jar +0 -0
  74. data/lib/neo4j/mapping/decl_relationship_dsl.rb +0 -214
  75. data/lib/neo4j/mapping/rule.rb +0 -158
  76. data/lib/neo4j/mapping/rule_node.rb +0 -176
  77. data/lib/neo4j/migrations.rb +0 -12
  78. data/lib/neo4j/migrations/global_migration.rb +0 -29
  79. data/lib/neo4j/migrations/lazy_migration_mixin.rb +0 -47
  80. data/lib/neo4j/migrations/migration_mixin.rb +0 -78
  81. data/lib/neo4j/node_mixin.rb +0 -4
  82. data/lib/neo4j/node_relationship.rb +0 -161
  83. data/lib/neo4j/node_traverser.rb +0 -224
  84. data/lib/neo4j/relationship_mixin.rb +0 -4
  85. data/lib/neo4j/relationship_traverser.rb +0 -92
@@ -1,33 +0,0 @@
1
- module Neo4j
2
- module Functions
3
- class Count < Function
4
- def initialize
5
- @property = '_classname'
6
- end
7
-
8
- def calculate?(changed_property)
9
- true
10
- end
11
-
12
- def delete(rule_name, rule_node, old_value)
13
- key = rule_node_property(rule_name)
14
- rule_node[key] ||= 0
15
- rule_node[key] -= 1
16
- end
17
-
18
- def add(rule_name, rule_node, new_value)
19
- key = rule_node_property(rule_name)
20
- rule_node[key] ||= 0
21
- rule_node[key] += 1
22
- end
23
-
24
- def update(*)
25
- # we are only counting, not interested in property changes
26
- end
27
-
28
- def self.function_name
29
- :count
30
- end
31
- end
32
- end
33
- end
@@ -1,72 +0,0 @@
1
- module Neo4j
2
- module Functions
3
-
4
- # The base class of rule functions.
5
- #
6
- # You are expected to at least implement two methods:
7
- # * update :: update the rule node value of this function
8
- # * function_name :: the name of this function, the name of the generated method - A class method !
9
- #
10
- class Function
11
-
12
- # Initialize the the function with a property which is usually the same as the function identity.
13
- # See the #calculate? method how this property is used.
14
- #
15
- def initialize(property)
16
- @property = property.to_s
17
- end
18
-
19
- def to_s
20
- "Function #{self.class.function_name} function_id: #{function_id}"
21
- end
22
-
23
- # Decides if the function should be called are not
24
- #
25
- def calculate?(changed_property)
26
- @property == changed_property
27
- end
28
-
29
-
30
- # The identity of the function.
31
- # Used to identify function.
32
- #
33
- # ==== Example
34
- # Person.sum(:young, :age)
35
- #
36
- # In the example above the property :age is the used to identify which function will be called
37
- # since there could be several sum method. In the example we want use the sum method that uses the :age property.
38
- #
39
- def function_id
40
- @property
41
- end
42
-
43
- # The value of the rule
44
- def value(rule_node, rule_name)
45
- key = rule_node_property(rule_name)
46
- rule_node[key] || 0
47
- end
48
-
49
- # Called when a node is removed from a rule group
50
- # Default is calling update method which is expected to be implemented in a subclass
51
- def delete(rule_name, rule_node, old_value)
52
- update(rule_name, rule_node, old_value, nil)
53
- end
54
-
55
- # Called when a node is added to a rule group
56
- # Default is calling update method which is expected to be implemented in a subclass
57
- def add(rule_name, rule_node, new_value)
58
- update(rule_name, rule_node, nil, new_value)
59
- end
60
-
61
- # the name of the property that holds the value of the function
62
- def rule_node_property(rule_name)
63
- self.class.rule_node_property(self.class.function_name, rule_name, @property)
64
- end
65
-
66
- def self.rule_node_property(function_name, rule_name, prop)
67
- "_#{function_name}_#{rule_name}_#{prop}"
68
- end
69
-
70
- end
71
- end
72
- end
@@ -1,27 +0,0 @@
1
- module Neo4j
2
- module Functions
3
-
4
- class Sum < Function
5
- # Updates the function's value.
6
- # Called after the transactions commits and a property has been changed on a node.
7
- #
8
- # ==== Arguments
9
- # * rule_name :: the name of the rule group
10
- # * rule_node :: the node which contains the value of this function
11
- # * old_value new value :: the changed value of the property (when the transaction commits)
12
- def update(rule_name, rule_node, old_value, new_value)
13
- key = rule_node_property(rule_name)
14
- rule_node[key] ||= 0
15
- old_value ||= 0
16
- new_value ||= 0
17
- rule_node[key] += new_value - old_value
18
- end
19
-
20
- def self.function_name
21
- :sum
22
- end
23
- end
24
-
25
-
26
- end
27
- end
@@ -1,214 +0,0 @@
1
- module Neo4j::Mapping
2
-
3
-
4
- # A DSL for declared relationships has_n and has_one
5
- # This DSL will be used to create accessor methods for relationships.
6
- # Instead of using the 'raw' Neo4j::NodeMixin#rels method where one needs to know
7
- # the name of relationship and direction one can use the generated accessor methods.
8
- #
9
- # The DSL can also be used to specify a mapping to a Ruby class for a relationship, see Neo4j::Relationships::DeclRelationshipDsl#relationship
10
- #
11
- # ==== Example
12
- #
13
- # class Folder
14
- # include Neo4j::NodeMixin
15
- # property :name
16
- # # Declaring a Many relationship to any other node
17
- # has_n(:files)
18
- # end
19
- #
20
- # class File
21
- # include Neo4j::NodeMixin
22
- # # declaring a incoming relationship from Folder's relationship files
23
- # has_one(:folder).from(Folder, :files)
24
- # end
25
- #
26
- # The following methods will be generated:
27
- # <b>Folder#files</b> :: returns an Enumerable of outgoing nodes for relationship 'files'
28
- # <b>Folder#files_rels</b> :: returns an Enumerable of outgoing relationships for relationship 'files'
29
- # <b>File#folder</b> :: for adding one node for the relationship 'files' from the outgoing Folder node
30
- # <b>File#folder_rel</b> :: for accessing relationship 'files' from the outgoing Folder node
31
- # <b>File#folder</b> :: for accessing nodes from relationship 'files' from the outgoing Folder node
32
- #
33
- class DeclRelationshipDsl
34
- include Neo4j::ToJava
35
-
36
- attr_reader :target_class, :direction, :rel_type
37
-
38
- def initialize(method_id, has_one, target_class, params)
39
- @direction = :outgoing
40
- @method_id = method_id
41
- @has_one = has_one
42
- @rel_type = method_id
43
- @target_class = target_class
44
- end
45
-
46
- def to_s
47
- "DeclRelationshipDsl #{object_id} dir: #{@direction} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
48
- end
49
-
50
- def has_one?
51
- @has_one
52
- end
53
-
54
- def each_node(node, direction, raw = false, &block) #:nodoc:
55
- type = type_to_java(rel_type)
56
- dir = dir_to_java(direction)
57
- node._java_node.getRelationships(type, dir).each do |rel|
58
- other = raw ? rel.getOtherNode(node) : rel.getOtherNode(node).wrapper
59
- block.call other
60
- end
61
- end
62
-
63
- def incoming? #:nodoc:
64
- @direction == :incoming
65
- end
66
-
67
- def single_node(node) #:nodoc:
68
- rel = single_relationship(node)
69
- rel && rel.other_node(node).wrapper
70
- end
71
-
72
- def single_relationship(node) #:nodoc:
73
- node._java_node.rel(direction, rel_type)
74
- end
75
-
76
- def _all_relationships(node) #:nodoc:
77
- type = type_to_java(rel_type)
78
- dir = dir_to_java(direction)
79
- node._java_node.getRelationships(type, dir)
80
- end
81
-
82
- def all_relationships(node) #:nodoc:
83
- Neo4j::RelationshipTraverser.new(node._java_node, [rel_type], direction)
84
- end
85
-
86
- def create_relationship_to(node, other) # :nodoc:
87
- from, to = incoming? ? [other, node] : [node, other]
88
- java_type = type_to_java(rel_type)
89
-
90
- rel = from._java_node.create_relationship_to(to._java_node, java_type)
91
- rel[:_classname] = relationship_class.to_s if relationship_class
92
- rel.wrapper
93
- end
94
-
95
- # Specifies an outgoing relationship.
96
- # The name of the outgoing class will be used as a prefix for the relationship used.
97
- #
98
- # ==== Arguments
99
- # clazz:: to which class this relationship goes
100
- # relationship:: optional, the relationship to use
101
- #
102
- # ==== Example
103
- # class FolderNode
104
- # include Neo4j::NodeMixin
105
- # has_n(:files).to(FileNode)
106
- # end
107
- #
108
- # folder = FolderNode.new
109
- # # generate a relationship between folder and file of type 'FileNode#files'
110
- # folder.files << FileNode.new
111
- #
112
- def to(*args)
113
- @direction = :outgoing
114
-
115
- if (args.size > 1)
116
- raise "only one argument expected - the class of the node this relationship points to, got #{args.inspect}"
117
- elsif (Class === args[0])
118
- # handle e.g. has_n(:friends).to(class)
119
- @target_class = args[0]
120
- @rel_type = "#{@target_class}##{@method_id}"
121
- else
122
- raise "Expected a class for, got #{args[0]}"
123
- end
124
- self
125
- end
126
-
127
- # Specifies an incoming relationship.
128
- # Will use the outgoing relationship given by the from class.
129
- #
130
- # ==== Example, with prefix FileNode
131
- # class FolderNode
132
- # include Neo4j::NodeMixin
133
- # has_n(:files).to(FileNode)
134
- # end
135
- #
136
- # class FileNode
137
- # include Neo4j::NodeMixin
138
- # # will only traverse any incoming relationship of type files from node FileNode
139
- # has_one(:folder).from(FileNode, :files)
140
- # end
141
- #
142
- # file = FileNode.new
143
- # # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
144
- # file.folder = FolderNode.new
145
- #
146
- # ==== Example, without prefix
147
- #
148
- # class FolderNode
149
- # include Neo4j::NodeMixin
150
- # has_n(:files)
151
- # end
152
- #
153
- # class FileNode
154
- # include Neo4j::NodeMixin
155
- # has_one(:folder).from(:files) # will traverse any incoming relationship of type files
156
- # end
157
- #
158
- # file = FileNode.new
159
- # # create an outgoing relationship of type 'FileNode#files' from folder node to file
160
- # file.folder = FolderNode.new
161
- #
162
- #
163
- def from(*args)
164
- @direction = :incoming
165
-
166
- if (args.size > 1)
167
- # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
168
- @rel_type = "#{@target_class}##{args[1]}"
169
- @target_class = args[0]
170
- other_class_dsl = @target_class._decl_rels[args[1]]
171
- if other_class_dsl
172
- @relationship = other_class_dsl.relationship_class
173
- else
174
- Neo4j.logger.warn "Unknown outgoing relationship #{args[1]} on #{@target_class}"
175
- end
176
- elsif (Symbol === args[0])
177
- # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
178
- @rel_type = args[0]
179
- else
180
- raise "Expected a symbol for, got #{args[0]}"
181
- end
182
- self
183
- end
184
-
185
- # Specifies which relationship ruby class to use for the relationship
186
- #
187
- # ==== Example
188
- #
189
- # class OrderLine
190
- # include Neo4j::RelationshipMixin
191
- # property :units
192
- # property :unit_price
193
- # end
194
- #
195
- # class Order
196
- # property :total_cost
197
- # property :dispatched
198
- # has_n(:products).to(Product).relationship(OrderLine)
199
- # end
200
- #
201
- # order = Order.new
202
- # order.products << Product.new
203
- # order.products_rels.first # => OrderLine
204
- #
205
- def relationship(rel_class)
206
- @relationship = rel_class
207
- self
208
- end
209
-
210
- def relationship_class # :nodoc:
211
- @relationship
212
- end
213
- end
214
- end
@@ -1,158 +0,0 @@
1
- module Neo4j::Mapping
2
-
3
-
4
- # Holds all defined rules and trigger them when an event is received.
5
- #
6
- # See Neo4j::Mapping::ClassMethods::Rule
7
- #
8
- class Rule #:nodoc:
9
-
10
- attr_reader :rule_name, :filter, :triggers, :functions
11
-
12
- def initialize(rule_name, props, &block)
13
- @rule_name = rule_name
14
- @triggers = props[:triggers]
15
- @functions = props[:functions]
16
- @triggers = [@triggers] if @triggers && !@triggers.respond_to?(:each)
17
- @functions = [@functions] if @functions && !@functions.respond_to?(:each)
18
- @filter = block
19
- end
20
-
21
- def to_s
22
- "Rule #{rule_name} props=#{props.inspect}"
23
- end
24
-
25
- def find_function(function_name, function_id)
26
- function_id = function_id.to_s
27
- @functions && @functions.find{|f| f.function_id == function_id && f.class.function_name == function_name}
28
- end
29
-
30
- # Reconstruct the properties given when created this rule
31
- # Needed when inheriting a rule and we want to duplicate a rule
32
- def props
33
- props = {}
34
- props[:triggers] = @triggers if @triggers
35
- props[:functions] = @functions if @functions
36
- props
37
- end
38
-
39
- def functions_for(property)
40
- @functions && @functions.find_all { |f| f.calculate?(property) }
41
- end
42
-
43
- def execute_filter(node)
44
- if @filter.nil?
45
- true
46
- elsif @filter.arity != 1
47
- node.wrapper.instance_eval(&@filter)
48
- else
49
- @filter.call(node)
50
- end
51
- end
52
-
53
- # ------------------------------------------------------------------------------------------------------------------
54
- # Class Methods
55
- # ------------------------------------------------------------------------------------------------------------------
56
-
57
- class << self
58
- def add(clazz, rule_name, props, &block)
59
- rule_node = rule_node_for(clazz.to_s)
60
- rule_node.remove_rule(rule_name) # remove any previously inherited rules
61
- rule_node.add_rule(rule_name, props, &block)
62
- end
63
-
64
- def rule_names_for(clazz)
65
- rule_node = rule_node_for(clazz)
66
- rule_node.rules.map { |rule| rule.rule_name }
67
- end
68
-
69
- def rule_node_for(clazz)
70
- return nil if clazz.nil?
71
- @rule_nodes ||= {}
72
- @rule_nodes[clazz.to_s] ||= RuleNode.new(clazz)
73
- end
74
-
75
- def inherit(parent_class, subclass)
76
- # copy all the rules
77
- if rule_node = rule_node_for(parent_class)
78
- rule_node.inherit(subclass)
79
- end
80
- end
81
-
82
- def delete(clazz)
83
- if rule_node = rule_node_for(clazz)
84
- rule_node.delete_node
85
- end
86
- end
87
-
88
- def trigger?(node)
89
- classname = node[:_classname]
90
- @rule_nodes && classname && rule_node_for(classname)
91
- end
92
-
93
- def trigger_rules(node, *changes)
94
- classname = node[:_classname]
95
- return unless classname # there are no rules if there is not a :_classname property
96
- rule_node = rule_node_for(classname)
97
- rule_node.execute_rules(node, *changes)
98
-
99
- # recursively add relationships for all the parent classes with rules that also pass for this node
100
- if (clazz = eval("#{classname}.superclass")) && clazz.include?(Neo4j::NodeMixin)
101
- rule_node = rule_node_for(clazz)
102
- rule_node && rule_node.execute_rules(node, *changes)
103
- end
104
- end
105
-
106
-
107
- # ----------------------------------------------------------------------------------------------------------------
108
- # Event handling methods
109
- # ----------------------------------------------------------------------------------------------------------------
110
-
111
- def on_relationship_created(rel, *)
112
- trigger_start_node = trigger?(rel._start_node)
113
- trigger_end_node = trigger?(rel._end_node)
114
- trigger_rules(rel._start_node) if trigger_start_node
115
- trigger_rules(rel._end_node) if trigger_end_node
116
- end
117
-
118
- def on_property_changed(node, *changes)
119
- trigger_rules(node, *changes) if trigger?(node)
120
- end
121
-
122
- def on_node_deleted(node, old_properties, data)
123
- # have we deleted a rule node ?
124
- del_rule_node = @rule_nodes && @rule_nodes.values.find{|rn| rn.rule_node?(node)}
125
- del_rule_node && del_rule_node.clear_rule_node
126
- return if del_rule_node
127
-
128
- # do we have prop_aggregations for this
129
- clazz = old_properties['_classname']
130
- rule_node = rule_node_for(clazz)
131
- return if rule_node.nil?
132
-
133
- id = node.getId
134
- rule_node.rules.each do |rule|
135
- next if rule.functions.nil?
136
- rule_name = rule.rule_name.to_s
137
-
138
- # is the rule node deleted ?
139
- deleted_rule_node = data.deletedNodes.find{|n| n == rule_node.rule_node}
140
- next if deleted_rule_node
141
-
142
- rule.functions.each do |function|
143
- next unless data.deletedRelationships.find do |r|
144
- r.getEndNode().getId() == id && r.rel_type == rule_name
145
- end
146
- previous_value = old_properties[function.function_id]
147
- function.delete(rule_name, rule_node.rule_node, previous_value) if previous_value
148
- end if rule.functions
149
- end
150
- end
151
-
152
- def on_neo4j_started(*)
153
- @rule_nodes.each_value { |rule_node| rule_node.on_neo4j_started } if @rule_nodes
154
- end
155
-
156
- end
157
- end
158
- end