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