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,12 +0,0 @@
1
- # This is copied from Rails Active Support since it has been depricated and I still need it
2
-
3
- # Taken from: https://raw.github.com/lifo/docrails/dd6c3676af3fa6019c53a59f62c4fd14966be728/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
4
-
5
- # Changes made:
6
- # - Remove deprecation warnings
7
- # - Ignore if already available from ActiveSupport
8
- #
9
- # Can't use class_attribute because we want to use the same value for all subclasses
10
-
11
-
12
- require 'neo4j/core_ext/class/rewrite_inheritable_attributes.rb'
@@ -1,170 +0,0 @@
1
- require 'active_support/core_ext/object/duplicable'
2
- require 'active_support/core_ext/array/extract_options'
3
-
4
- # Retained for backward compatibility. Methods are now included in Class.
5
- module ClassInheritableAttributes # :nodoc:
6
- end
7
-
8
- # It is recommended to use <tt>class_attribute</tt> over methods defined in this file. Please
9
- # refer to documentation for <tt>class_attribute</tt> for more information. Officially it is not
10
- #
11
- # Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of
12
- # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
13
- # to, for example, an array without those additions being shared with either their parent, siblings, or
14
- # children. This is unlike the regular class-level attributes that are shared across the entire hierarchy.
15
- #
16
- # The copies of inheritable parent attributes are added to subclasses when they are created, via the
17
- # +inherited+ hook.
18
- #
19
- # class Person
20
- # class_inheritable_accessor :hair_colors
21
- # end
22
- #
23
- # Person.hair_colors = [:brown, :black, :blonde, :red]
24
- # Person.hair_colors # => [:brown, :black, :blonde, :red]
25
- # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
26
- #
27
- # To opt out of the instance writer method, pass :instance_writer => false.
28
- # To opt out of the instance reader method, pass :instance_reader => false.
29
- #
30
- # class Person
31
- # class_inheritable_accessor :hair_colors :instance_writer => false, :instance_reader => false
32
- # end
33
- #
34
- # Person.new.hair_colors = [:brown] # => NoMethodError
35
- # Person.new.hair_colors # => NoMethodError
36
- class Class # :nodoc:
37
- def class_inheritable_reader(*syms)
38
- options = syms.extract_options!
39
- syms.each do |sym|
40
- next if sym.is_a?(Hash)
41
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
42
- def self.#{sym} # def self.after_add
43
- read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
44
- end # end
45
- #
46
- #{" #
47
- def #{sym} # def after_add
48
- self.class.#{sym} # self.class.after_add
49
- end # end
50
- " unless options[:instance_reader] == false } # # the reader above is generated unless options[:instance_reader] == false
51
- EOS
52
- end
53
- end
54
-
55
- def class_inheritable_writer(*syms)
56
- options = syms.extract_options!
57
- syms.each do |sym|
58
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
59
- def self.#{sym}=(obj) # def self.color=(obj)
60
- write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:color, obj)
61
- end # end
62
- #
63
- #{" #
64
- def #{sym}=(obj) # def color=(obj)
65
- self.class.#{sym} = obj # self.class.color = obj
66
- end # end
67
- " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
68
- EOS
69
- end
70
- end
71
-
72
- def class_inheritable_array_writer(*syms)
73
- options = syms.extract_options!
74
- syms.each do |sym|
75
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
76
- def self.#{sym}=(obj) # def self.levels=(obj)
77
- write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:levels, obj)
78
- end # end
79
- #
80
- #{" #
81
- def #{sym}=(obj) # def levels=(obj)
82
- self.class.#{sym} = obj # self.class.levels = obj
83
- end # end
84
- " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
85
- EOS
86
- end
87
- end
88
-
89
- def class_inheritable_hash_writer(*syms)
90
- options = syms.extract_options!
91
- syms.each do |sym|
92
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
93
- def self.#{sym}=(obj) # def self.nicknames=(obj)
94
- write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:nicknames, obj)
95
- end # end
96
- #
97
- #{" #
98
- def #{sym}=(obj) # def nicknames=(obj)
99
- self.class.#{sym} = obj # self.class.nicknames = obj
100
- end # end
101
- " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
102
- EOS
103
- end
104
- end
105
-
106
- def class_inheritable_accessor(*syms)
107
- class_inheritable_reader(*syms)
108
- class_inheritable_writer(*syms)
109
- end
110
-
111
- def class_inheritable_array(*syms)
112
- class_inheritable_reader(*syms)
113
- class_inheritable_array_writer(*syms)
114
- end
115
-
116
- def class_inheritable_hash(*syms)
117
- class_inheritable_reader(*syms)
118
- class_inheritable_hash_writer(*syms)
119
- end
120
-
121
- def inheritable_attributes
122
- @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
123
- end
124
-
125
- def write_inheritable_attribute(key, value)
126
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
127
- @inheritable_attributes = {}
128
- end
129
- inheritable_attributes[key] = value
130
- end
131
-
132
- def write_inheritable_array(key, elements)
133
- write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
134
- write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
135
- end
136
-
137
- def write_inheritable_hash(key, hash)
138
- write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
139
- write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
140
- end
141
-
142
- def read_inheritable_attribute(key)
143
- inheritable_attributes[key]
144
- end
145
-
146
- def reset_inheritable_attributes
147
- @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
148
- end
149
-
150
- private
151
- # Prevent this constant from being created multiple times
152
- EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze
153
-
154
- def inherited_with_inheritable_attributes(child)
155
- inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
156
-
157
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
158
- new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
159
- else
160
- new_inheritable_attributes = Hash[inheritable_attributes.map do |(key, value)|
161
- [key, value.duplicable? ? value.dup : value]
162
- end]
163
- end
164
-
165
- child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
166
- end
167
-
168
- alias inherited_without_inheritable_attributes inherited
169
- alias inherited inherited_with_inheritable_attributes
170
- end
@@ -1,158 +0,0 @@
1
- require 'neo4j/config'
2
- require 'neo4j/event_handler'
3
- require 'neo4j/transaction'
4
-
5
- module Neo4j
6
- # Wraps both Java Neo4j GraphDatabaseService and Lucene.
7
- # You can access the raw java neo4j and lucene db's with the <tt>graph</tt> and <tt>lucene</tt>
8
- # properties.
9
- #
10
- # This class is also responsible for checking if there is already a running neo4j database.
11
- # If one tries to start an already started database then a read only instance to neo4j will be used.
12
- #
13
- class Database
14
- attr_reader :graph, :lucene, :event_handler, :storage_path
15
-
16
- alias_method :index, :lucene # needed by cypher
17
-
18
- def initialize()
19
- @event_handler = EventHandler.new
20
- end
21
-
22
- def start #:nodoc:
23
- return if running?
24
- @running = true
25
- @storage_path = Config.storage_path
26
-
27
- begin
28
- if self.class.locked?
29
- start_readonly_graph_db
30
- elsif Neo4j::Config['ha.db']
31
- start_ha_graph_db
32
- Neo4j.migrate!
33
- else
34
- start_local_graph_db
35
- Neo4j.migrate!
36
- end
37
- rescue
38
- @running = false
39
- raise
40
- end
41
-
42
- at_exit { shutdown }
43
- end
44
-
45
- def start_readonly_graph_db #:nodoc:
46
- Neo4j.logger.info "Starting Neo4j in readonly mode since the #{@storage_path} is locked"
47
- @graph = org.neo4j.kernel.EmbeddedReadOnlyGraphDatabase.new(@storage_path, Config.to_java_map)
48
- @lucene = @graph.index
49
- end
50
-
51
- def start_local_graph_db #:nodoc:
52
- Neo4j.logger.info "Starting local Neo4j using db #{@storage_path}"
53
- @graph = org.neo4j.kernel.EmbeddedGraphDatabase.new(@storage_path, Config.to_java_map)
54
- @graph.register_transaction_event_handler(@event_handler)
55
- @lucene = @graph.index
56
- @event_handler.neo4j_started(self)
57
- end
58
-
59
- # needed by cypher
60
- def getNodeById(id) #:nodoc:
61
- Neo4j::Node.load(id)
62
- end
63
-
64
- # needed by cypher
65
- def getRelationshipById(id) #:nodoc:
66
- Neo4j::Relationship.load(id)
67
- end
68
-
69
- def start_ha_graph_db
70
- Neo4j.logger.info "starting Neo4j in HA mode, machine id: #{Neo4j.config['ha.server_id']} at #{Neo4j.config['ha.server']} db #{@storage_path}"
71
- # Modify the public base classes for the HA Node and Relationships
72
- # (instead of private org.neo4j.kernel.HighlyAvailableGraphDatabase::LookupNode)
73
- @graph = org.neo4j.kernel.HighlyAvailableGraphDatabase.new(@storage_path, Neo4j.config.to_java_map)
74
- @graph.register_transaction_event_handler(@event_handler)
75
- @lucene = @graph.index
76
- @event_handler.neo4j_started(self)
77
- end
78
-
79
- def start_external_db(external_graph_db)
80
- begin
81
- @running = true
82
- @graph = external_graph_db
83
- Neo4j.migrate!
84
- @graph.register_transaction_event_handler(@event_handler)
85
- @lucene = @graph.index #org.neo4j.index.impl.lucene.LuceneIndexProvider.new
86
- @event_handler.neo4j_started(self)
87
- Neo4j.logger.info("Started with external db")
88
- rescue
89
- @running = false
90
- raise
91
- end
92
- end
93
-
94
- def running? #:nodoc:
95
- @running
96
- end
97
-
98
- # Returns true if the neo4j db was started in read only mode.
99
- # This can occur if the database was locked (it was already one instance running).
100
- def read_only?
101
- @graph.java_class == org.neo4j.kernel.EmbeddedGraphDatabase
102
- end
103
-
104
- # check if the database is locked. A neo4j database is locked when the database is running.
105
- def self.locked?
106
- lock_file = File.join(Neo4j.config.storage_path, 'neostore')
107
- return false unless File.exist?(lock_file)
108
- rfile = java.io.RandomAccessFile.new(lock_file, 'rw')
109
- begin
110
- lock = rfile.getChannel.tryLock
111
- lock.release if lock
112
- return lock == nil # we got the lock, so that means it is not locked.
113
- rescue Exception => e
114
- return false
115
- end
116
- end
117
-
118
- def shutdown #:nodoc:
119
- if @running
120
- @graph.unregister_transaction_event_handler(@event_handler) unless read_only?
121
- @event_handler.neo4j_shutdown(self)
122
- @graph.shutdown
123
- @graph = nil
124
- @lucene = nil
125
- @running = false
126
- @neo4j_manager = nil
127
- end
128
-
129
- end
130
-
131
-
132
- def management(jmx_clazz) #:nodoc:
133
- @neo4j_manager ||= org.neo4j.management.Neo4jManager.new(@graph.get_management_bean(org.neo4j.jmx.Kernel.java_class))
134
- @neo4j_manager.getBean(jmx_clazz.java_class)
135
- end
136
-
137
- def begin_tx #:nodoc:
138
- @graph.begin_tx
139
- end
140
-
141
-
142
- def each_node #:nodoc:
143
- iter = @graph.all_nodes.iterator
144
- while (iter.hasNext)
145
- yield iter.next.wrapper
146
- end
147
- end
148
-
149
- def _each_node #:nodoc:
150
- iter = @graph.all_nodes.iterator
151
- while (iter.hasNext)
152
- yield iter.next
153
- end
154
- end
155
-
156
- end
157
-
158
- end
data/lib/neo4j/equal.rb DELETED
@@ -1,21 +0,0 @@
1
- module Neo4j
2
-
3
- # == This mixin is used for both nodes and relationships to decide if two entities are equal or not.
4
- #
5
- module Equal
6
- def equal?(o)
7
- eql?(o)
8
- end
9
-
10
- def eql?(o)
11
- return false unless o.respond_to?(:getId)
12
- o.getId == getId
13
- end
14
-
15
- def ==(o)
16
- eql?(o)
17
- end
18
-
19
- end
20
-
21
- end
@@ -1,263 +0,0 @@
1
- module Neo4j
2
-
3
- # == Handles Transactional Events
4
- #
5
- # You can use this to receive event before the transaction commits.
6
- # The following events are supported:
7
- # * <tt>on_neo4j_started</tt>
8
- # * <tt>on_neo4j_shutdown</tt>
9
- # * <tt>on_node_created</tt>
10
- # * <tt>on_node_deleted</tt>
11
- # * <tt>on_relationship_created</tt>
12
- # * <tt>on_relationship_deleted</tt>
13
- # * <tt>on_property_changed</tt>
14
- # * <tt>on_rel_property_changed</tt>
15
- # * <tt>on_after_commit</tt>
16
- #
17
- # ==== on_neo4j_started(db)
18
- #
19
- # Called when the neo4j engine starts.
20
- # Notice that the neo4j will be started automatically when the first neo4j operation is performed.
21
- # You can also start Neo4j: <tt>Neo4j.start</tt>
22
- #
23
- # * <tt>db</tt> :: the Neo4j::Database instance
24
- #
25
- # ==== on_neo4j_shutdown(db)
26
- #
27
- # Called when the neo4j engine shutdown. You don't need to call <tt>Neo4j.shutdown</tt> since
28
- # the it will automatically be shutdown when the application exits (using the at_exit ruby hook).
29
- #
30
- # * <tt>db</tt> :: the Neo4j::Database instance
31
- #
32
- # ==== on_after_commit(data, state)
33
- #
34
- # Called after the transaction has successfully committed.
35
- # See http://api.neo4j.org/1.4/org/neo4j/graphdb/event/TransactionEventHandler.html for the data and state parameter.
36
- #
37
- # ==== on_node_created(node)
38
- #
39
- # * <tt>node</tt> :: the node that was created
40
- #
41
- # ==== on_node_deleted(node, old_props, deleted_relationship_set, deleted_node_identity_map)
42
- #
43
- # * <tt>node</tt> :: the node that was deleted
44
- # * <tt>old_props</tt> :: a hash of the old properties this node had
45
- # * <tt>deleted_relationship_set</tt> :: the set of deleted relationships. See Neo4j::RelationshipSet
46
- # * <tt>deleted_node_identity_map</tt> :: the identity map of deleted nodes. The key is the node id, and the value is the node
47
- #
48
- # ==== on_relationship_created(rel, created_node_identity_map)
49
- #
50
- # * <tt>rel</tt> :: the relationship that was created
51
- # * <tt>created_node_identity_map</tt> :: the identity map of created nodes. The key is the node id, and the value is the node
52
- #
53
- # ==== on_relationship_deleted(rel, old_props, deleted_relationship_set, deleted_node_identity_map)
54
- #
55
- # * <tt>rel</tt> :: the relationship that was created
56
- # * <tt>old_props</tt> :: a hash of the old properties this relationship had
57
- # * <tt>deleted_relationship_set</tt> :: the set of deleted relationships. See Neo4j::RelationshipSet
58
- # * <tt>deleted_node_identity_map</tt> :: the identity map of deleted nodes. The key is the node id, and the value is the node
59
- #
60
- # ==== on_property_changed(node, key, old_value, new_value)
61
- #
62
- # * <tt>node</tt> :: the node
63
- # * <tt>key</tt> :: the name of the property that was changed (String)
64
- # * <tt>old_value</tt> :: old value of the property
65
- # * <tt>new_value</tt> :: new value of the property
66
- #
67
- # ==== on_rel_property_changed(rel, key, old_value, new_value)
68
- #
69
- # * <tt>rel</tt> :: the node that was created
70
- # * <tt>key</tt> :: the name of the property that was changed (String)
71
- # * <tt>old_value</tt> :: old value of the property
72
- # * <tt>new_value</tt> :: new value of the property
73
- #
74
- # ==== classes_changed(class_change_map)
75
- # * <tt>class_change_map</tt> :: a hash with class names as keys, and class changes as values. See Neo4j::ClassChanges
76
- #
77
- # == Usage
78
- #
79
- # class MyListener
80
- # def on_node_deleted(node, old_props, deleted_relationship_set, deleted_node_identity_map)
81
- # end
82
- # end
83
- #
84
- # # to add an listener without starting neo4j:
85
- # Neo4j.unstarted_db.event_handler.add(MyListener.new)
86
- #
87
- # You only need to implement the methods that you need.
88
- #
89
- class EventHandler
90
- include org.neo4j.graphdb.event.TransactionEventHandler
91
-
92
- def initialize
93
- @listeners = []
94
- end
95
-
96
-
97
- def after_commit(data, state)
98
- @listeners.each {|li| li.on_after_commit(data, state) if li.respond_to?(:on_after_commit)}
99
- end
100
-
101
- def after_rollback(data, state)
102
- end
103
-
104
- def before_commit(data)
105
- class_change_map = java.util.HashMap.new
106
- created_node_identity_map = iterate_created_nodes(data.created_nodes, class_change_map)
107
- deleted_node_identity_map = deleted_node_identity_map(data.deleted_nodes)
108
- deleted_relationship_set = relationship_set(data.deleted_relationships)
109
- removed_node_properties_map = property_map(data.removed_node_properties)
110
- removed_relationship_properties_map = property_map(data.removed_relationship_properties)
111
- add_deleted_nodes(data, class_change_map, removed_node_properties_map)
112
- empty_map = java.util.HashMap.new
113
- data.assigned_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, tx_data.value) unless tx_data.key == '_classname'}
114
- data.removed_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, nil) unless deleted_node_identity_map.containsKey(tx_data.entity.getId) }
115
- data.deleted_nodes.each { |node| node_deleted(node, removed_node_properties_map.get(node.getId)||empty_map, deleted_relationship_set, deleted_node_identity_map)}
116
- data.created_relationships.each {|rel| relationship_created(rel, created_node_identity_map)}
117
- data.deleted_relationships.each {|rel| relationship_deleted(rel, removed_relationship_properties_map.get(rel.getId)||empty_map, deleted_relationship_set, deleted_node_identity_map)}
118
- data.assigned_relationship_properties.each { |tx_data| rel_property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, tx_data.value) }
119
- data.removed_relationship_properties.each {|tx_data| rel_property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, nil) unless deleted_relationship_set.contains_rel?(tx_data.entity) }
120
- classes_changed(class_change_map)
121
- rescue Exception => e
122
- # since these exceptions gets swallowed
123
- puts "ERROR in before commit hook #{e}"
124
- puts e.backtrace.join("\n")
125
- end
126
-
127
-
128
- def iterate_created_nodes(nodes, class_change_map)
129
- identity_map = java.util.HashMap.new
130
- nodes.each do |node|
131
- identity_map.put(node.neo_id,node) #using put due to a performance regression in JRuby 1.6.4
132
- instance_created(node, class_change_map)
133
- node_created(node)
134
- end
135
- identity_map
136
- end
137
-
138
- def deleted_node_identity_map(nodes)
139
- identity_map = java.util.HashMap.new
140
- nodes.each{|node| identity_map.put(node.neo_id,node)} #using put due to a performance regression in JRuby 1.6.4
141
- identity_map
142
- end
143
-
144
- def relationship_set(relationships)
145
- relationship_set = Neo4j::RelationshipSet.new#(relationships.size)
146
- relationships.each{|rel| relationship_set.add(rel)}
147
- relationship_set
148
- end
149
-
150
- def property_map(properties)
151
- map = java.util.HashMap.new
152
- properties.each do |property|
153
- map(property.entity.getId, map).put(property.key, property.previously_commited_value)
154
- end
155
- map
156
- end
157
-
158
- def map(key,map)
159
- map.get(key) || add_map(key,map)
160
- end
161
-
162
- def add_map(key,map)
163
- map.put(key, java.util.HashMap.new)
164
- map.get(key)
165
- end
166
-
167
- def add(listener)
168
- @listeners << listener unless @listeners.include?(listener)
169
- end
170
-
171
- def remove(listener)
172
- @listeners.delete(listener)
173
- end
174
-
175
- def remove_all
176
- @listeners = []
177
- end
178
-
179
- def print
180
- puts "Listeners #{@listeners.size}"
181
- @listeners.each {|li| puts " Listener '#{li}'"}
182
- end
183
-
184
- def neo4j_started(db)
185
- @listeners.each { |li| li.on_neo4j_started(db) if li.respond_to?(:on_neo4j_started) }
186
- end
187
-
188
- def neo4j_shutdown(db)
189
- @listeners.each { |li| li.on_neo4j_shutdown(db) if li.respond_to?(:on_neo4j_shutdown) }
190
- end
191
-
192
- def node_created(node)
193
- @listeners.each {|li| li.on_node_created(node) if li.respond_to?(:on_node_created)}
194
- end
195
-
196
- def node_deleted(node,old_properties, deleted_relationship_set, deleted_node_identity_map)
197
- @listeners.each {|li| li.on_node_deleted(node,old_properties, deleted_relationship_set, deleted_node_identity_map) if li.respond_to?(:on_node_deleted)}
198
- end
199
-
200
- def relationship_created(relationship, created_node_identity_map)
201
- @listeners.each {|li| li.on_relationship_created(relationship, created_node_identity_map) if li.respond_to?(:on_relationship_created)}
202
- end
203
-
204
- def relationship_deleted(relationship, old_props, deleted_relationship_set, deleted_node_identity_map)
205
- @listeners.each {|li| li.on_relationship_deleted(relationship, old_props, deleted_relationship_set, deleted_node_identity_map) if li.respond_to?(:on_relationship_deleted)}
206
- end
207
-
208
- def property_changed(node, key, old_value, new_value)
209
- @listeners.each {|li| li.on_property_changed(node, key, old_value, new_value) if li.respond_to?(:on_property_changed)}
210
- end
211
-
212
- def rel_property_changed(rel, key, old_value, new_value)
213
- @listeners.each {|li| li.on_rel_property_changed(rel, key, old_value, new_value) if li.respond_to?(:on_rel_property_changed)}
214
- end
215
-
216
- def add_deleted_nodes(data, class_change_map, removed_node_properties_map)
217
- data.deleted_nodes.each{|node| instance_deleted(node, removed_node_properties_map, class_change_map)}
218
- end
219
-
220
- def instance_created(node, class_change_map)
221
- classname = node[:_classname]
222
- class_change(classname, class_change_map).add(node) if classname
223
- end
224
-
225
- def instance_deleted(node, removed_node_properties_map, class_change_map)
226
- properties = removed_node_properties_map.get(node.getId)
227
- if properties
228
- classname = properties.get("_classname")
229
- class_change(classname, class_change_map).delete(node) if classname
230
- end
231
- end
232
-
233
- def class_change(classname, class_change_map)
234
- class_change_map.put(classname, ClassChanges.new) if class_change_map.get(classname).nil?
235
- class_change_map.get(classname)
236
- end
237
-
238
- def classes_changed(changed_class_map)
239
- @listeners.each {|li| li.classes_changed(changed_class_map) if li.respond_to?(:classes_changed)}
240
- end
241
- end
242
-
243
- class ClassChanges
244
- attr_accessor :added, :deleted
245
-
246
- def initialize
247
- self.added = []
248
- self.deleted = []
249
- end
250
-
251
- def add(node)
252
- self.added << node
253
- end
254
-
255
- def delete(node)
256
- self.deleted << node
257
- end
258
-
259
- def net_change
260
- self.added.size - self.deleted.size
261
- end
262
- end
263
- end