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,72 +1,74 @@
1
1
  module Neo4j
2
- module Rails
2
+ module Rails
3
3
  # Handle all the created_at, updated_at, created_on, updated_on type stuff.
4
- module Timestamps
5
- extend ActiveSupport::Concern
4
+ module Timestamps
5
+ extend ActiveSupport::Concern
6
6
 
7
- TIMESTAMP_PROPERTIES = [ :created_at, :created_on, :updated_at, :updated_on ]
7
+ TIMESTAMP_PROPERTIES = [:created_at, :created_on, :updated_at, :updated_on]
8
8
 
9
9
  included do
10
10
  before_create :create_timestamp
11
11
  before_save :update_timestamp, :if => :new_or_changed?
12
12
  end
13
- # Set the timestamps for this model if timestamps is set to true in the config
14
- # and the model is set up with the correct property name, e.g.:
15
- #
16
- # class Trackable < Neo4j::Rails::Model
17
- # property :updated_at, :type => DateTime
18
- # end
19
- def update_timestamp
20
- #definition provided whenever an :updated_at property is defined
21
- end
22
-
23
- # Set the timestamps for this model if timestamps is set to true in the config
24
- # and the model is set up with the correct property name, e.g.:
25
- #
26
- # class Trackable < Neo4j::Rails::Model
27
- # property :created_at, :type => DateTime
28
- # end
29
- def create_timestamp
30
- #definition provided whenever an :created_at property is defined
31
- end
13
+ # Set the timestamps for this model if timestamps is set to true in the config
14
+ # and the model is set up with the correct property name, e.g.:
15
+ #
16
+ # class Trackable < Neo4j::Rails::Model
17
+ # property :updated_at, :type => DateTime
18
+ # end
19
+ def update_timestamp
20
+ #definition provided whenever an :updated_at property is defined
21
+ end
32
22
 
33
- # Write the timestamp as a Date, DateTime or Time depending on the property type
34
- def write_date_or_timestamp(attribute)
35
- value = case self.class._decl_props[attribute][:type].to_s
36
- when "DateTime"
37
- DateTime.now
38
- when "Date"
39
- Date.today
40
- when "Time"
41
- Time.now
42
- end
23
+ # Set the timestamps for this model if timestamps is set to true in the config
24
+ # and the model is set up with the correct property name, e.g.:
25
+ #
26
+ # class Trackable < Neo4j::Rails::Model
27
+ # property :created_at, :type => DateTime
28
+ # end
29
+ def create_timestamp
30
+ #definition provided whenever an :created_at property is defined
31
+ end
43
32
 
44
- send("#{attribute}=", value)
45
- end
33
+ # Write the timestamp as a Date, DateTime or Time depending on the property type
34
+ def write_date_or_timestamp(attribute)
35
+ value = case self.class._decl_props[attribute.to_sym][:type].to_s
36
+ when "DateTime"
37
+ DateTime.now
38
+ when "Date"
39
+ Date.today
40
+ when "Time"
41
+ Time.now
42
+ end
43
+ send("#{attribute}=", value)
44
+ end
46
45
 
47
46
  def new_or_changed?
48
47
  self.new? or self.changed?
49
48
  end
50
49
 
51
- module ClassMethods
52
- def property_setup(property, options)
53
- super
54
- define_timestamp_method(:create_timestamp,:created_at) if property == :created_at
55
- define_timestamp_method(:update_timestamp,:updated_at) if property == :updated_at
56
- # ensure there's always a type on the timestamp properties
57
- if Neo4j::Config[:timestamps] && TIMESTAMP_PROPERTIES.include?(property)
58
- _decl_props[property][:type] ||= Time
59
- end
60
- end
50
+ module ClassMethods
51
+ def property_setup(property, options)
52
+ super
53
+ define_timestamp_method(:create_timestamp, :created_at) if property == :created_at
54
+ define_timestamp_method(:update_timestamp, :updated_at) if property == :updated_at
55
+ # ensure there's always a type on the timestamp properties
56
+ if Neo4j::Config[:timestamps] && TIMESTAMP_PROPERTIES.include?(property)
57
+ if _decl_props[property][:converter] == Neo4j::TypeConverters::DefaultConverter
58
+ _decl_props[property][:type] = Time
59
+ _decl_props[property][:converter] = Neo4j::TypeConverters.converter(Time)
60
+ end
61
+ end
62
+ end
61
63
 
62
- def define_timestamp_method(method_name, property)
63
- class_eval <<-RUBY, __FILE__, __LINE__
64
+ def define_timestamp_method(method_name, property)
65
+ class_eval <<-RUBY, __FILE__, __LINE__
64
66
  def #{method_name}
65
67
  write_date_or_timestamp(:#{property}) if Neo4j::Config[:timestamps]
66
68
  end
67
69
  RUBY
68
- end
69
- end
70
- end
71
- end
70
+ end
71
+ end
72
+ end
73
+ end
72
74
  end
@@ -38,8 +38,16 @@ module Neo4j
38
38
  tx.finish
39
39
  Thread.current[:neo4j_transaction] = nil
40
40
  Thread.current[:neo4j_transaction_fail] = nil
41
+ rescue Exception => e
42
+ if Neo4j::Config[:debug_java] && e.respond_to?(:cause)
43
+ puts "Java Exception in a transaction, cause: #{e.cause}"
44
+ e.cause.print_stack_trace
45
+ end
46
+ tx.failure unless tx.nil?
47
+ raise
41
48
  end
42
49
 
50
+
43
51
  def filter(*, &block)
44
52
  run &block
45
53
  end
@@ -60,7 +68,7 @@ module Neo4j
60
68
  ret
61
69
  end
62
70
  end
63
-
71
+
64
72
  private
65
73
  def new
66
74
  Thread.current[:neo4j_transaction] = Neo4j::Transaction.new
@@ -11,7 +11,7 @@ module Neo4j
11
11
 
12
12
  def setup(klass)
13
13
  @attributes.each do |attribute|
14
- if klass.index_type_for(attribute) != @validator.index_type
14
+ if klass.index_type(attribute) != @validator.index_type
15
15
  raise index_error_message(klass,attribute,@validator.index_type)
16
16
  end
17
17
  end
@@ -80,7 +80,7 @@ module Neo4j
80
80
  # @param [ Integer ] number The version number to retrieve.
81
81
  # Returns nil in case a version is not found.
82
82
  def version(number)
83
- snapshot = Version.find(:model_classname => _classname, :instance_id => neo_id, :number => number) {|query| query.first.nil? ? nil : query.first.end_node}
83
+ snapshot = Version.find(:model_classname => _classname, :instance_id => neo_id, :number => number) {|query| query.first.nil? ? nil : query.first.end_node.wrapper}
84
84
  snapshot.props.each_pair{|k,v| snapshot.assign(k,Neo4j::TypeConverters.to_ruby(self.class, k, v))} if !snapshot.nil?
85
85
  snapshot
86
86
  end
@@ -129,7 +129,7 @@ module Neo4j
129
129
  end
130
130
 
131
131
  def each_versionable_relationship
132
- rule_relationships = java.util.HashSet.new(Neo4j::Rule::Rule.rule_names_for(_classname))
132
+ rule_relationships = java.util.HashSet.new(Neo4j::Wrapper::Rule::Rule.rule_names_for(_classname))
133
133
  self._java_node.getRelationships().each do |rel|
134
134
  yield rel unless rule_relationships.contains(rel.getType().name().to_sym) || rel.getType.name.to_sym == :version
135
135
  end
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = "2.0.0.alpha.5"
2
+ VERSION = "2.0.0.alpha.6"
3
3
  end
@@ -1,51 +1,52 @@
1
1
  require 'orm_adapter'
2
2
 
3
3
  module Neo4j
4
- module Rails
5
- class Model
6
- extend ::OrmAdapter::ToAdapter
7
-
8
- class OrmAdapter < ::OrmAdapter::Base
9
- # Do not consider these to be part of the class list
10
- def self.except_classes
11
- @@except_classes ||= []
12
- end
13
-
14
- # Gets a list of the available models for this adapter
15
- def self.model_classes
16
- ::Neo4j::Rails::Model.descendants.to_a.select{|k| !except_classes.include?(k.name)}
17
- end
18
-
19
- # get a list of column names for a given class
20
- def column_names
21
- klass._decl_props.keys
22
- end
23
-
24
- # Get an instance by id of the model
25
- def get!(id)
26
- klass.find!(wrap_key(id))
27
- end
28
-
29
- # Get an instance by id of the model
30
- def get(id)
31
- klass.find(wrap_key(id))
32
- end
33
-
34
- # Find the first instance matching conditions
35
- def find_first(conditions)
36
- klass.first(conditions)
37
- end
38
-
39
- # Find all models matching conditions
40
- def find_all(conditions)
41
- klass.all(conditions)
42
- end
43
-
44
- # Create a model using attributes
45
- def create!(attributes)
46
- klass.create!(attributes)
47
- end
48
- end
49
- end
4
+ module Rails
5
+ class Model
6
+ extend ::OrmAdapter::ToAdapter
7
+
8
+ class OrmAdapter < ::OrmAdapter::Base
9
+ # Do not consider these to be part of the class list
10
+ def self.except_classes
11
+ @@except_classes ||= []
12
+ end
13
+
14
+ # Gets a list of the available models for this adapter
15
+ def self.model_classes
16
+ ::Neo4j::Rails::Model.descendants.to_a.select { |k| !except_classes.include?(k.name) }
17
+ end
18
+
19
+ # get a list of column names for a given class
20
+ def column_names
21
+ klass._decl_props.keys
22
+ end
23
+
24
+ # Get an instance by id of the model
25
+ def get!(id)
26
+ klass.find!(wrap_key(id))
27
+ end
28
+
29
+ # Get an instance by id of the model
30
+ def get(id)
31
+ klass.find(wrap_key(id))
32
+ end
33
+
34
+ # Find the first instance matching conditions
35
+ def find_first(conditions)
36
+ klass.first(conditions)
37
+ end
38
+
39
+ # Find all models matching conditions
40
+ def find_all(conditions)
41
+ klass.all(conditions)
42
+ end
43
+
44
+ # Create a model using attributes
45
+ def create!(attributes)
46
+ klass.create!(attributes)
47
+ end
48
+ end
49
+ end
50
50
  end
51
51
  end
52
+
data/neo4j.gemspec CHANGED
@@ -32,5 +32,5 @@ It comes included with the Apache Lucene document database.
32
32
  s.add_dependency('orm_adapter', ">= 0.0.3")
33
33
  s.add_dependency("activemodel", ">= 3.0.0", "< 3.3")
34
34
  s.add_dependency("railties", ">= 3.0.0", "< 3.3")
35
- s.add_dependency("neo4j-community", "1.7.0.alpha.1")
35
+ s.add_dependency("neo4j-wrapper", '0.0.5')
36
36
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: neo4j
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 2.0.0.alpha.5
5
+ version: 2.0.0.alpha.6
6
6
  platform: java
7
7
  authors:
8
8
  - Andreas Ronge
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-27 00:00:00 Z
13
+ date: 2012-04-15 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: orm_adapter
@@ -52,14 +52,14 @@ dependencies:
52
52
  type: :runtime
53
53
  version_requirements: *id003
54
54
  - !ruby/object:Gem::Dependency
55
- name: neo4j-community
55
+ name: neo4j-wrapper
56
56
  prerelease: false
57
57
  requirement: &id004 !ruby/object:Gem::Requirement
58
58
  none: false
59
59
  requirements:
60
60
  - - "="
61
61
  - !ruby/object:Gem::Version
62
- version: 1.7.0.alpha.1
62
+ version: 0.0.5
63
63
  type: :runtime
64
64
  version_requirements: *id004
65
65
  description: |
@@ -93,61 +93,27 @@ files:
93
93
  - lib/tasks/upgrade_v2/upgrade_v2.rake
94
94
  - lib/tasks/upgrade_v2/lib/upgrade_v2.rb
95
95
  - lib/orm_adapter/adapters/neo4j.rb
96
- - lib/neo4j/identity_map.rb
97
- - lib/neo4j/event_handler.rb
98
- - lib/neo4j/model.rb
99
- - lib/neo4j/paginated.rb
100
- - lib/neo4j/config.rb
101
- - lib/neo4j/transaction.rb
102
- - lib/neo4j/neo4j.rb
103
- - lib/neo4j/node.rb
104
- - lib/neo4j/load.rb
105
- - lib/neo4j/database.rb
106
- - lib/neo4j/relationship_set.rb
96
+ - lib/neo4j/performance.rb
107
97
  - lib/neo4j/version.rb
108
- - lib/neo4j/equal.rb
109
- - lib/neo4j/relationship.rb
110
- - lib/neo4j/to_java.rb
111
- - lib/neo4j/algo/algo.rb
112
- - lib/neo4j/has_list/mapping.rb
113
- - lib/neo4j/has_list/class_methods.rb
114
- - lib/neo4j/has_list/has_list.rb
115
- - lib/neo4j/property/property.rb
116
- - lib/neo4j/property/class_methods.rb
117
- - lib/neo4j/traversal/rel_expander.rb
118
- - lib/neo4j/traversal/filter_predicate.rb
119
- - lib/neo4j/traversal/prune_evaluator.rb
120
- - lib/neo4j/traversal/traversal.rb
121
- - lib/neo4j/traversal/traverser.rb
122
- - lib/neo4j/relationship_mixin/relationship_mixin.rb
123
- - lib/neo4j/relationship_mixin/class_methods.rb
124
- - lib/neo4j/type_converters/type_converters.rb
125
- - lib/neo4j/core_ext/class/inheritable_attributes.rb
126
- - lib/neo4j/core_ext/class/rewrite_inheritable_attributes.rb
127
- - lib/neo4j/migrations/migrations.rb
128
- - lib/neo4j/migrations/lazy_node_mixin.rb
129
- - lib/neo4j/migrations/extensions.rb
130
- - lib/neo4j/migrations/node_mixin.rb
131
- - lib/neo4j/migrations/migration.rb
132
- - lib/neo4j/migrations/class_methods.rb
133
- - lib/neo4j/migrations/ref_node_wrapper.rb
134
- - lib/neo4j/rels/traverser.rb
135
- - lib/neo4j/rels/rels.rb
136
98
  - lib/neo4j/rails/attributes.rb
137
99
  - lib/neo4j/rails/rack_middleware.rb
138
100
  - lib/neo4j/rails/model.rb
139
101
  - lib/neo4j/rails/validations.rb
102
+ - lib/neo4j/rails/identity.rb
140
103
  - lib/neo4j/rails/persistence.rb
104
+ - lib/neo4j/rails/node_persistance.rb
141
105
  - lib/neo4j/rails/serialization.rb
142
106
  - lib/neo4j/rails/railtie.rb
143
107
  - lib/neo4j/rails/rails.rb
108
+ - lib/neo4j/rails/relationship_persistence.rb
144
109
  - lib/neo4j/rails/observer.rb
110
+ - lib/neo4j/rails/nested_attributes.rb
145
111
  - lib/neo4j/rails/transaction.rb
146
112
  - lib/neo4j/rails/timestamps.rb
147
113
  - lib/neo4j/rails/callbacks.rb
114
+ - lib/neo4j/rails/has_n.rb
148
115
  - lib/neo4j/rails/tx_methods.rb
149
116
  - lib/neo4j/rails/accept_id.rb
150
- - lib/neo4j/rails/rel_persistence.rb
151
117
  - lib/neo4j/rails/finders.rb
152
118
  - lib/neo4j/rails/relationship.rb
153
119
  - lib/neo4j/rails/compositions.rb
@@ -156,34 +122,9 @@ files:
156
122
  - lib/neo4j/rails/relationships/relationships.rb
157
123
  - lib/neo4j/rails/relationships/storage.rb
158
124
  - lib/neo4j/rails/versioning/versioning.rb
159
- - lib/neo4j/rails/mapping/property.rb
160
125
  - lib/neo4j/rails/validations/associated.rb
161
126
  - lib/neo4j/rails/validations/uniqueness.rb
162
127
  - lib/neo4j/rails/validations/non_nil.rb
163
- - lib/neo4j/index/indexer.rb
164
- - lib/neo4j/index/lucene_query.rb
165
- - lib/neo4j/index/indexer_registry.rb
166
- - lib/neo4j/index/class_methods.rb
167
- - lib/neo4j/index/index.rb
168
- - lib/neo4j/batch/inserter.rb
169
- - lib/neo4j/batch/indexer.rb
170
- - lib/neo4j/batch/rule_inserter.rb
171
- - lib/neo4j/batch/rule_node.rb
172
- - lib/neo4j/batch/batch.rb
173
- - lib/neo4j/has_n/decl_relationship_dsl.rb
174
- - lib/neo4j/has_n/has_n.rb
175
- - lib/neo4j/has_n/mapping.rb
176
- - lib/neo4j/has_n/class_methods.rb
177
- - lib/neo4j/node_mixin/node_mixin.rb
178
- - lib/neo4j/node_mixin/class_methods.rb
179
- - lib/neo4j/rule/rule.rb
180
- - lib/neo4j/rule/rule_node.rb
181
- - lib/neo4j/rule/class_methods.rb
182
- - lib/neo4j/rule/event_listener.rb
183
- - lib/neo4j/rule/functions/function.rb
184
- - lib/neo4j/rule/functions/count.rb
185
- - lib/neo4j/rule/functions/sum.rb
186
- - lib/neo4j/rule/functions/functions.rb
187
128
  - config/locales/en.yml
188
129
  - config/neo4j/config.yml
189
130
  - README.rdoc
@@ -1,294 +0,0 @@
1
- # external neo4j dependencies
2
- require 'neo4j/to_java'
3
-
4
- module Neo4j
5
-
6
-
7
- class Algo
8
- include Enumerable
9
- include ToJava
10
-
11
- class EstimateEvaluator #:nodoc
12
- include org.neo4j.graphalgo.EstimateEvaluator
13
- include ToJava
14
-
15
- def initialize(&evaluator)
16
- @evaluator = evaluator
17
- end
18
-
19
- # Implements T getCost(Node node, Node goal)
20
- # Estimate the weight of the remaining path from one node to another.
21
- def get_cost(node, goal)
22
- @evaluator.call(node, goal)
23
- end
24
- end
25
-
26
- class CostEvaluator #:nodoc
27
- include org.neo4j.graphalgo.CostEvaluator
28
- include ToJava
29
-
30
- def initialize(&evaluator)
31
- @evaluator = evaluator
32
- end
33
-
34
- # Implements the Java Method: T getCost(Relationship relationship, Direction direction)
35
- # From the JavaDoc: <pre>
36
- # This is the general method for looking up costs for relationships.
37
- # This can do anything, like looking up a property or running some small calculation.
38
- # Parameters:
39
- # relationship -
40
- # direction - The direction in which the relationship is being evaluated, either Direction.INCOMING or Direction.OUTGOING.
41
- # Returns:
42
- # The cost for this edge/relationship
43
- # </pre>
44
- def get_cost(relationship, direction)
45
- @evaluator.call(relationship, dir_from_java(direction))
46
- end
47
- end
48
-
49
- def initialize(from, to, &factory_proc) #:nodoc:
50
- @from = from
51
- @to = to
52
- @factory_proc = factory_proc
53
- @type_and_dirs = []
54
-
55
- end
56
-
57
- def _depth #:nodoc:
58
- @depth || java.lang.Integer::MAX_VALUE
59
- end
60
-
61
- def _expander #:nodoc:
62
- expander = @expander
63
- expander ||= @type_and_dirs.empty? ? org.neo4j.kernel.Traversal.expanderForAllTypes() : org.neo4j.kernel.Traversal.expanderForTypes(*@type_and_dirs)
64
- expander
65
- end
66
-
67
- def _cost_evaluator #:nodoc:
68
- raise "Algorithm requeries a cost evalulator, use the cost_evaluator to provide one" unless @cost_evaluator
69
- @cost_evaluator
70
- end
71
-
72
- def _estimate_evaluator #:nodoc:
73
- raise "Algorithm requeries a estimate evaluator, use the estimate_evaluator to provide one" unless @estimate_evaluator
74
- @estimate_evaluator
75
- end
76
-
77
- # Specifies which outgoing relationship should be traversed for the graph algorithm
78
- #
79
- # ==== Parameters
80
- # * rel :: relationship type (symbol)
81
- def outgoing(rel)
82
- @type_and_dirs << type_to_java(rel)
83
- @type_and_dirs << dir_to_java(:outgoing)
84
- self
85
- end
86
-
87
- # Specifies which incoming relationship should be traversed for the graph algorithm
88
- #
89
- # ==== Parameters
90
- # * rel :: relationship type (symbol)
91
- def incoming(rel)
92
- @type_and_dirs << type_to_java(rel)
93
- @type_and_dirs << dir_to_java(:incoming)
94
- self
95
- end
96
-
97
- # Specifies which relationship should be traversed for the graph algorithm
98
- #
99
- # ==== Example
100
- # The following:
101
- #
102
- # Neo4j::Algo.shortest_path(@x,@y).expand{|node| node._rels(:outgoing, :friends)}
103
- #
104
- # Is the same as
105
- # Neo4j::Algo.shortest_path(@x,@y).outgoing(:friends)
106
- #
107
- # ==== Parameters
108
- # * expander_proc :: a proc relationship type (symbol)
109
- def expand(&expander_proc)
110
- @expander = (Neo4j::Traversal::RelExpander.create_pair(&expander_proc))
111
- self
112
- end
113
-
114
- # If only a single path should be returned,
115
- # default for some algorithms, like shortest_path
116
- def single
117
- @single = true
118
- self
119
- end
120
-
121
- # See #single
122
- # Not sure if this method is useful
123
- def many
124
- @single = false
125
- end
126
-
127
- # The depth of the traversal
128
- # Notice not all algorithm uses this argument (aStar and dijkstra)
129
- def depth(depth)
130
- @depth = depth
131
- self
132
- end
133
-
134
- # Specifies a cost evaluator for the algorithm.
135
- # Only available for the aStar and dijkstra algorithms.
136
- #
137
- # ==== Example
138
- # Neo4j::Algo.dijkstra(@x,@y).cost_evaluator{|rel,*| rel[:weight]}
139
- #
140
- def cost_evaluator(&cost_evaluator_proc)
141
- @cost_evaluator = CostEvaluator.new(&cost_evaluator_proc)
142
- self
143
- end
144
-
145
- # Specifies an evaluator that returns an (optimistic) estimation of the cost to get from the current node (in the traversal) to the end node.
146
- # Only available for the aStar algorithm.
147
- #
148
- # The provided proc estimate the weight of the remaining path from one node to another.
149
- # The proc takes two parameters:
150
- # * node :: the node to estimate the weight from.
151
- # * goal :: the node to estimate the weight to.
152
- #
153
- # The proc should return an estimation of the weight of the path from the first node to the second.
154
- #
155
- # ==== Example
156
- #
157
- # Neo4j::Algo.a_star(@x,@y).cost_evaluator{...}.estimate_evaluator{|node,goal| some calucalation retuning a Float}
158
- #
159
- def estimate_evaluator(&estimate_evaluator_proc)
160
- @estimate_evaluator = EstimateEvaluator.new(&estimate_evaluator_proc)
161
- self
162
- end
163
-
164
- # Specifies that nodes should be returned from as result
165
- # See also #rels
166
- def nodes
167
- @path_finder_method = :nodes
168
- self
169
- end
170
-
171
- # Specifies that relationships should be returned from as result
172
- # See also #nodes
173
- #
174
- def rels
175
- @path_finder_method = :relationships
176
- self
177
- end
178
-
179
-
180
- # So that one can call directly method on the PathFinder result from an executed algorithm.
181
- def method_missing(m, *args, &block)
182
- execute_algo.send(m, *args)
183
- end
184
-
185
- def each(&block) #:nodoc:
186
- if @single && @path_finder_method
187
- execute_algo.send(@path_finder_method).each &block
188
- else
189
- traversal = execute_algo
190
- traversal.each &block if traversal
191
- end
192
- end
193
-
194
- def execute_algo #:nodoc:
195
- instance = self.instance_eval(&@factory_proc)
196
- if @single
197
- instance.find_single_path(@from._java_node, @to._java_node)
198
- else
199
- instance.find_all_paths(@from._java_node, @to._java_node)
200
- end
201
- end
202
-
203
- # Returns an instance of Neo4j::Algo which can find all available paths between two nodes.
204
- # These returned paths can contain loops (i.e. a node can occur more than once in any returned path).
205
- def self.all_paths(from, to)
206
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.all_paths(_expander, _depth) }
207
- end
208
-
209
- # See #all_paths, returns the first path found
210
- def self.all_path(from, to)
211
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.all_paths(_expander, _depth) }.single
212
- end
213
-
214
- # Returns an instance of Neo4j::Algo which can find all simple paths between two nodes.
215
- # These returned paths cannot contain loops (i.e. a node cannot occur more than once in any returned path).
216
- def self.all_simple_paths(from, to)
217
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.all_simple_paths(_expander, _depth) }
218
- end
219
-
220
- # See #all_simple_paths, returns the first path found
221
- def self.all_simple_path(from, to)
222
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.all_simple_paths(_expander, _depth) }.single
223
- end
224
-
225
- # Returns an instance of Neo4j::Algo which can find all shortest paths (that is paths with as short Path.length() as possible) between two nodes.
226
- # These returned paths cannot contain loops (i.e. a node cannot occur more than once in any returned path).
227
- def self.shortest_paths(from, to)
228
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.shortest_path(_expander, _depth) }
229
- end
230
-
231
- # See #shortest_paths, returns the first path found
232
- def self.shortest_path(from, to)
233
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.shortest_path(_expander, _depth) }.single
234
- end
235
-
236
- # Returns an instance of Neo4j::Algo which uses the Dijkstra algorithm to find the cheapest path between two nodes.
237
- # The definition of "cheap" is the lowest possible cost to get from the start node to the end node, where the cost is returned from costEvaluator.
238
- # These returned paths cannot contain loops (i.e. a node cannot occur more than once in any returned path).
239
- # See http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm for more information.
240
- #
241
- # Example
242
- #
243
- # Neo4j::Algo.dijkstra_path(node_a,node_b).cost_evaluator{|rel,*| rel[:weight]}.rels
244
- #
245
- def self.dijkstra_paths(from, to)
246
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.dijkstra(_expander, _cost_evaluator) }
247
- end
248
-
249
- # See #dijkstra_paths, returns the first path found
250
- #
251
- def self.dijkstra_path(from, to)
252
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.dijkstra(_expander, _cost_evaluator) }.single
253
- end
254
-
255
- # Returns an instance of Neo4j::Algo which uses the A* algorithm to find the cheapest path between two nodes.
256
- # The definition of "cheap" is the lowest possible cost to get from the start node to the end node, where the cost is returned from lengthEvaluator and estimateEvaluator. These returned paths cannot contain loops (i.e. a node cannot occur more than once in any returned path).
257
- # See http://en.wikipedia.org/wiki/A*_search_algorithm for more information.
258
- #
259
- # Expacts an cost evaluator and estimate evaluator, see Algo#cost_evaluator and Algo#estimate_evaluator
260
- #
261
- # Example:
262
- #
263
- # Neo4j::Algo.a_star_path(@x,@y).cost_evaluator{|rel,*| rel[:weight]}.estimate_evaluator{|node,goal| returns a float value}
264
- #
265
- def self.a_star_paths(from, to)
266
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.a_star(_expander, _cost_evaluator, _estimate_evaluator) }
267
- end
268
-
269
- # See #a_star_paths, returns the first path found
270
- #
271
- def self.a_star_path(from, to)
272
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.a_star(_expander, _cost_evaluator, _estimate_evaluator) }.single
273
- end
274
-
275
- # Returns an instance of Neo4j::Algo can find all paths of a certain length(depth) between two nodes.
276
- # These returned paths cannot contain loops (i.e. a node cannot occur more than once in any returned path).
277
- # Expects setting the depth parameter (the lenghto of the path) by the Algo#depth method.
278
- #
279
- # Example:
280
- #
281
- # Neo4j::Algo.with_length_paths(node_a,node_b).depth(2).each {|x| puts "Node #{x}"}
282
- #
283
- def self.with_length_paths(from,to)
284
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.paths_with_length(_expander, _depth) }
285
- end
286
-
287
- # See #with_length_paths, returns the first path found
288
- #
289
- def self.with_length_path(from,to)
290
- Algo.new(from, to) { org.neo4j.graphalgo.GraphAlgoFactory.paths_with_length(_expander, _depth) }.single
291
- end
292
-
293
- end
294
- end