neo4j 1.0.0.beta.27-java → 1.0.0.beta.28-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 (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