neo4j 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG +141 -0
  2. data/CONTRIBUTORS +15 -0
  3. data/Gemfile +3 -0
  4. data/README.rdoc +2015 -0
  5. data/lib/neo4j.old/batch_inserter.rb +144 -0
  6. data/lib/neo4j.old/config.rb +138 -0
  7. data/lib/neo4j.old/event_handler.rb +73 -0
  8. data/lib/neo4j.old/extensions/activemodel.rb +158 -0
  9. data/lib/neo4j.old/extensions/aggregate.rb +12 -0
  10. data/lib/neo4j.old/extensions/aggregate/aggregate_enum.rb +40 -0
  11. data/lib/neo4j.old/extensions/aggregate/ext/node_mixin.rb +69 -0
  12. data/lib/neo4j.old/extensions/aggregate/node_aggregate.rb +8 -0
  13. data/lib/neo4j.old/extensions/aggregate/node_aggregate_mixin.rb +331 -0
  14. data/lib/neo4j.old/extensions/aggregate/node_aggregator.rb +216 -0
  15. data/lib/neo4j.old/extensions/aggregate/node_group.rb +43 -0
  16. data/lib/neo4j.old/extensions/aggregate/prop_group.rb +30 -0
  17. data/lib/neo4j.old/extensions/aggregate/property_enum.rb +24 -0
  18. data/lib/neo4j.old/extensions/aggregate/props_aggregate.rb +8 -0
  19. data/lib/neo4j.old/extensions/aggregate/props_aggregate_mixin.rb +31 -0
  20. data/lib/neo4j.old/extensions/aggregate/props_aggregator.rb +80 -0
  21. data/lib/neo4j.old/extensions/find_path.rb +117 -0
  22. data/lib/neo4j.old/extensions/graph_algo.rb +1 -0
  23. data/lib/neo4j.old/extensions/graph_algo/all_simple_paths.rb +133 -0
  24. data/lib/neo4j.old/extensions/graph_algo/neo4j-graph-algo-0.3.jar +0 -0
  25. data/lib/neo4j.old/extensions/reindexer.rb +104 -0
  26. data/lib/neo4j.old/extensions/rest.rb +21 -0
  27. data/lib/neo4j.old/extensions/rest/rest.rb +336 -0
  28. data/lib/neo4j.old/extensions/rest/rest_mixin.rb +193 -0
  29. data/lib/neo4j.old/extensions/rest/server.rb +50 -0
  30. data/lib/neo4j.old/extensions/rest/stubs.rb +141 -0
  31. data/lib/neo4j.old/extensions/rest_master.rb +34 -0
  32. data/lib/neo4j.old/extensions/rest_slave.rb +31 -0
  33. data/lib/neo4j.old/extensions/tx_tracker.rb +392 -0
  34. data/lib/neo4j.old/indexer.rb +187 -0
  35. data/lib/neo4j.old/jars.rb +6 -0
  36. data/lib/neo4j.old/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  37. data/lib/neo4j.old/jars/neo4j-kernel-1.0.jar +0 -0
  38. data/lib/neo4j.old/mixins/java_list_mixin.rb +139 -0
  39. data/lib/neo4j.old/mixins/java_node_mixin.rb +205 -0
  40. data/lib/neo4j.old/mixins/java_property_mixin.rb +169 -0
  41. data/lib/neo4j.old/mixins/java_relationship_mixin.rb +60 -0
  42. data/lib/neo4j.old/mixins/migration_mixin.rb +157 -0
  43. data/lib/neo4j.old/mixins/node_mixin.rb +249 -0
  44. data/lib/neo4j.old/mixins/property_class_methods.rb +265 -0
  45. data/lib/neo4j.old/mixins/rel_class_methods.rb +167 -0
  46. data/lib/neo4j.old/mixins/relationship_mixin.rb +103 -0
  47. data/lib/neo4j.old/neo.rb +247 -0
  48. data/lib/neo4j.old/node.rb +49 -0
  49. data/lib/neo4j.old/reference_node.rb +15 -0
  50. data/lib/neo4j.old/relationship.rb +85 -0
  51. data/lib/neo4j.old/relationships/decl_relationship_dsl.rb +164 -0
  52. data/lib/neo4j.old/relationships/has_list.rb +101 -0
  53. data/lib/neo4j.old/relationships/has_n.rb +129 -0
  54. data/lib/neo4j.old/relationships/node_traverser.rb +138 -0
  55. data/lib/neo4j.old/relationships/relationship_dsl.rb +149 -0
  56. data/lib/neo4j.old/relationships/traversal_position.rb +50 -0
  57. data/lib/neo4j.old/relationships/wrappers.rb +51 -0
  58. data/lib/neo4j.old/search_result.rb +72 -0
  59. data/lib/neo4j.old/transaction.rb +254 -0
  60. data/lib/neo4j.old/version.rb +3 -0
  61. data/lib/neo4j.rb +50 -0
  62. data/lib/neo4j/config.rb +137 -0
  63. data/lib/neo4j/database.rb +43 -0
  64. data/lib/neo4j/equal.rb +22 -0
  65. data/lib/neo4j/event_handler.rb +91 -0
  66. data/lib/neo4j/index.rb +157 -0
  67. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  68. data/lib/neo4j/jars/lucene-core-2.9.2.jar +0 -0
  69. data/lib/neo4j/jars/lucene-core-3.0.1.jar +0 -0
  70. data/lib/neo4j/jars/neo4j-index-1.1.jar +0 -0
  71. data/lib/neo4j/jars/neo4j-kernel-1.1.1.jar +0 -0
  72. data/lib/neo4j/jars/neo4j-kernel-1.1.jar +0 -0
  73. data/lib/neo4j/jars/neo4j-lucene-index-0.1-20100916.085626-67.jar +0 -0
  74. data/lib/neo4j/mapping/class_methods/index.rb +21 -0
  75. data/lib/neo4j/mapping/class_methods/property.rb +139 -0
  76. data/lib/neo4j/mapping/class_methods/relationship.rb +96 -0
  77. data/lib/neo4j/mapping/class_methods/rule.rb +135 -0
  78. data/lib/neo4j/mapping/decl_relationship_dsl.rb +151 -0
  79. data/lib/neo4j/mapping/has_n.rb +117 -0
  80. data/lib/neo4j/mapping/node_mixin.rb +70 -0
  81. data/lib/neo4j/neo4j.rb +65 -0
  82. data/lib/neo4j/node.rb +82 -0
  83. data/lib/neo4j/node_mixin.rb +4 -0
  84. data/lib/neo4j/node_relationship.rb +60 -0
  85. data/lib/neo4j/node_traverser.rb +141 -0
  86. data/lib/neo4j/property.rb +72 -0
  87. data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
  88. data/lib/neo4j/rails/model.rb +210 -0
  89. data/lib/neo4j/rails/railtie.rb +16 -0
  90. data/lib/neo4j/rails/transaction.rb +29 -0
  91. data/lib/neo4j/rails/value.rb +43 -0
  92. data/lib/neo4j/relationship.rb +88 -0
  93. data/lib/neo4j/relationship_traverser.rb +57 -0
  94. data/lib/neo4j/to_java.rb +17 -0
  95. data/lib/neo4j/transaction.rb +69 -0
  96. data/lib/neo4j/version.rb +3 -0
  97. data/neo4j.gemspec +30 -0
  98. metadata +243 -0
@@ -0,0 +1,137 @@
1
+
2
+ module Neo4j
3
+
4
+
5
+ # Keeps configuration for neo4j.
6
+ #
7
+ # Neo4j::Config[:storage_path]:: is used for locating the neo4j database on the filesystem.
8
+ #
9
+ class Config
10
+ # This code is copied from merb-core/config.rb.
11
+ class << self
12
+ # Returns the hash of default config values for neo4j
13
+ #
14
+ # ==== Returns
15
+ # Hash:: The defaults for the config.
16
+ def defaults
17
+ @defaults ||= {
18
+ :storage_path => 'tmp/neo4j',
19
+ :lucene => {
20
+ :fulltext => org.neo4j.index.impl.lucene.LuceneIndexProvider::FULLTEXT_CONFIG,
21
+ :exact => org.neo4j.index.impl.lucene.LuceneIndexProvider::EXACT_CONFIG}
22
+ }
23
+ end
24
+
25
+
26
+ # Yields the configuration.
27
+ #
28
+ # ==== Block parameters
29
+ # c<Hash>:: The configuration parameters.
30
+ #
31
+ # ==== Examples
32
+ # Neo4j::Config.use do |config|
33
+ # config[:storage_path] = '/var/neo4j'
34
+ # end
35
+ #
36
+ # ==== Returns
37
+ # nil
38
+ def use
39
+ @configuration ||= {}
40
+ yield @configuration
41
+ nil
42
+ end
43
+
44
+
45
+ # Set the value of a config entry.
46
+ #
47
+ # ==== Parameters
48
+ # key<Object>:: The key to set the parameter for.
49
+ # val<Object>:: The value of the parameter.
50
+ #
51
+ def []=(key, val)
52
+ (@configuration ||= setup)[key] = val
53
+ end
54
+
55
+
56
+ # Gets the the value of a config entry
57
+ #
58
+ # ==== Parameters
59
+ # key<Object>:: The key of the config entry value we want
60
+ #
61
+ def [](key)
62
+ (@configuration ||= setup)[key]
63
+ end
64
+
65
+
66
+ # Remove the value of a config entry.
67
+ #
68
+ # ==== Parameters
69
+ # key<Object>:: The key of the parameter to delete.
70
+ #
71
+ # ==== Returns
72
+ # Object:: The value of the removed entry.
73
+ #
74
+ def delete(key)
75
+ @configuration.delete(key)
76
+ end
77
+
78
+
79
+ # Remove all configuration. This can be useful for testing purpose.
80
+ #
81
+ #
82
+ # ==== Returns
83
+ # nil
84
+ #
85
+ def delete_all
86
+ @configuration = nil
87
+ end
88
+
89
+
90
+ # Retrieve the value of a config entry, returning the provided default if the key is not present
91
+ #
92
+ # ==== Parameters
93
+ # key<Object>:: The key to retrieve the parameter for.
94
+ # default<Object>::
95
+ # The default value to return if the parameter is not set.
96
+ #
97
+ # ==== Returns
98
+ # Object:: The value of the configuration parameter or the default.
99
+ #
100
+ def fetch(key, default)
101
+ @configuration.fetch(key, default)
102
+ end
103
+
104
+ # Sets up the configuration
105
+ #
106
+ # ==== Returns
107
+ # The configuration as a hash.
108
+ #
109
+ def setup()
110
+ @configuration = {}
111
+ @configuration.merge!(defaults)
112
+ @configuration
113
+ end
114
+
115
+
116
+ # Returns the configuration as a hash.
117
+ #
118
+ # ==== Returns
119
+ # Hash:: The config as a hash.
120
+ #
121
+ def to_hash
122
+ @configuration
123
+ end
124
+
125
+ # Returns the config as YAML.
126
+ #
127
+ # ==== Returns
128
+ # String:: The config as YAML.
129
+ #
130
+ def to_yaml
131
+ require "yaml"
132
+ @configuration.to_yaml
133
+ end
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,43 @@
1
+ module Neo4j
2
+ class Database
3
+ attr_reader :graph, :lucene, :event_handler
4
+
5
+ def initialize()
6
+ @event_handler = EventHandler.new
7
+ end
8
+
9
+
10
+ def start
11
+ @running = true
12
+ @graph = org.neo4j.kernel.EmbeddedGraphDatabase.new(Config[:storage_path])
13
+ @lucene = org.neo4j.index.impl.lucene.LuceneIndexProvider.new(@graph)
14
+ @graph.register_transaction_event_handler(@event_handler)
15
+ @event_handler.neo4j_started(self)
16
+ end
17
+
18
+ def shutdown
19
+ @running = false
20
+ @graph.unregister_transaction_event_handler(@event_handler)
21
+ @event_handler.neo4j_shutdown(self)
22
+ @graph.shutdown
23
+ end
24
+
25
+ def running?
26
+ @running
27
+ end
28
+
29
+ def begin_tx
30
+ @graph.begin_tx
31
+ end
32
+
33
+
34
+ def each_node
35
+ iter = @graph.all_nodes.iterator
36
+ while (iter.hasNext)
37
+ yield Node.load_wrapper(iter.next)
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,22 @@
1
+ module Neo4j
2
+ module Equal
3
+ def neo_id
4
+ getId
5
+ end
6
+
7
+ def equal?(o)
8
+ eql?(o)
9
+ end
10
+
11
+ def eql?(o)
12
+ return false unless o.respond_to?(:getId)
13
+ o.getId == getId
14
+ end
15
+
16
+ def ==(o)
17
+ eql?(o)
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,91 @@
1
+ module Neo4j
2
+
3
+ # Handles events like a new node is created or deleted
4
+ class EventHandler
5
+ include org.neo4j.graphdb.event.TransactionEventHandler
6
+
7
+ def initialize
8
+ @listeners = []
9
+ end
10
+
11
+
12
+ def after_commit(data, state)
13
+ end
14
+
15
+ def after_rollback(data, state)
16
+ end
17
+
18
+ def before_commit(data)
19
+ data.created_nodes.each{|node| node_created(node)}
20
+ data.assigned_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, tx_data.value) }
21
+ data.removed_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, nil) unless data.deleted_nodes.include?(tx_data.entity) }
22
+ data.deleted_nodes.each { |node| node_deleted(node, deleted_properties_for(node,data))}
23
+ # TODO Add relationship properties callbacks
24
+ end
25
+
26
+ def deleted_properties_for(node, data)
27
+ data.removed_node_properties.find_all{|tx_data| tx_data.entity == node}.inject({}) do |memo, tx_data|
28
+ memo[tx_data.key] = tx_data.previously_commited_value
29
+ memo
30
+ end
31
+ end
32
+
33
+ def add(listener)
34
+ @listeners << listener unless @listeners.include?(listener)
35
+ end
36
+
37
+ def remove(listener)
38
+ @listeners.delete(listener)
39
+ end
40
+
41
+ def remove_all
42
+ @listeners = []
43
+ end
44
+
45
+ def print
46
+ puts "Listeners #{@listeners.size}"
47
+ @listeners.each_key {|li| puts " Listener '#{li}'"}
48
+ end
49
+
50
+ def neo4j_started(db)
51
+ @listeners.each { |li| li.on_neo4j_started(db) if li.respond_to?(:on_neo4j_started) }
52
+ end
53
+
54
+ def neo4j_shutdown(db)
55
+ @listeners.each { |li| li.on_neo4j_shutdown(db) if li.respond_to?(:on_neo4j_shutdown) }
56
+ end
57
+
58
+ def node_created(node)
59
+ @listeners.each {|li| li.on_node_created(node) if li.respond_to?(:on_node_created)}
60
+ end
61
+
62
+ def node_deleted(node,old_properties)
63
+ @listeners.each {|li| li.on_node_deleted(node,old_properties) if li.respond_to?(:on_node_deleted)}
64
+ end
65
+
66
+ def relationship_created(relationship)
67
+ @listeners.each {|li| li.on_relationship_created(relationship) if li.respond_to?(:on_relationship_created)}
68
+ end
69
+
70
+ def relationship_deleted(relationship)
71
+ @listeners.each {|li| li.on_relationship_deleted(relationship) if li.respond_to?(:on_relationship_deleted)}
72
+ end
73
+
74
+ def property_changed(node, key, old_value, new_value)
75
+ @listeners.each {|li| li.on_property_changed(node, key, old_value, new_value) if li.respond_to?(:on_property_changed)}
76
+ end
77
+
78
+ # TODO
79
+ def tx_finished(tx)
80
+ @listeners.each {|li| li.on_tx_finished(tx) if li.respond_to?(:on_tx_finished)}
81
+ end
82
+
83
+ def neo_started(neo_instance)
84
+ @listeners.each {|li| li.on_neo_started(neo_instance) if li.respond_to?(:on_neo_started)}
85
+ end
86
+
87
+ def neo_stopped(neo_instance)
88
+ @listeners.each {|li| li.on_neo_stopped(neo_instance) if li.respond_to?(:on_neo_stopped)}
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,157 @@
1
+ module Neo4j
2
+
3
+ module Index
4
+ def add_index(field, value=self[field])
5
+ self.class.add_index(wrapped_entity, field.to_s, value)
6
+ end
7
+
8
+ def rm_index(field, value=self[field])
9
+ self.class.rm_index(wrapped_entity, field.to_s, value)
10
+ end
11
+
12
+ module ClassMethods
13
+ extend Forwardable
14
+
15
+ def_delegators :@indexer, :index, :find, :index?, :index_type?, :clear_index_type, :rm_index_type, :add_index, :rm_index
16
+
17
+ # Sets which indexer should be used for the given class.
18
+ # Returns the old one if there was an old indexer.
19
+ def indexer(clazz)
20
+ old = @indexer
21
+ @@indexers ||= {}
22
+ if @@indexers.include?(clazz)
23
+ # we want to reuse an existing index
24
+ @indexer = @@indexers[clazz]
25
+ @indexer.include_trigger(self)
26
+ else
27
+ @indexer = Indexer.new(clazz)
28
+ @@indexers[clazz] = @indexer
29
+ end
30
+ old
31
+ end
32
+ end
33
+
34
+ class Indexer
35
+ attr_reader :index_name
36
+
37
+ def initialize(clazz)
38
+ @index_name = clazz.to_s
39
+
40
+ @indexes = {} # key = type, value = java neo4j index
41
+ @field_types = {} # key = field, value = type (e.g. :exact or :fulltext)
42
+ @triggered_by = clazz.to_s
43
+ end
44
+
45
+ # add an index on a field that will be automatically updated by events.
46
+ def index(field, conf = {})
47
+ type = conf[:type] || :exact
48
+ @field_types[field.to_s] = type
49
+ Neo4j.default_db.event_handler.add(self)
50
+ end
51
+
52
+ def index?(field)
53
+ @field_types.include?(field.to_s)
54
+ end
55
+
56
+ def index_type?(type)
57
+ @field_types.values.include?(type)
58
+ end
59
+
60
+ def add_index(entity, field, value)
61
+ index_for_field(field.to_s).add(entity, field, value)
62
+ end
63
+
64
+ def rm_index(entity, field, value)
65
+ index_for_field(field).remove(entity, field, value)
66
+ end
67
+
68
+ def find(query, type = :exact)
69
+ index = index_for_type(type)
70
+ hits = index.query(query)
71
+ if block_given?
72
+ begin
73
+ ret = yield hits
74
+ ensure
75
+ hits.close if hits
76
+ end
77
+ ret
78
+ else
79
+ hits
80
+ end
81
+ end
82
+
83
+ # clears the index, if no type is provided clear all types of indexes
84
+ def clear_index_type(type=nil)
85
+ if type
86
+ #raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
87
+ @indexes[type] && @indexes[type].clear
88
+ else
89
+ @indexes.each_value{|index| index.clear}
90
+ end
91
+ end
92
+
93
+ def rm_index_type(type=nil)
94
+ if type
95
+ #raise "can't remove index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
96
+ @field_types.delete_if {|k,v| v == type}
97
+ else
98
+ @field_types.clear
99
+ end
100
+ end
101
+
102
+ def index_for_field(field)
103
+ type = @field_types[field]
104
+ @indexes[type] ||= create_index_with(type)
105
+ end
106
+
107
+ def index_for_type(type)
108
+ @indexes[type] ||= create_index_with(type)
109
+ end
110
+
111
+ def lucene_config(type)
112
+ conf = Neo4j::Config[:lucene][type.to_sym]
113
+ raise "unknown lucene type #{type}" unless conf
114
+ conf
115
+ end
116
+
117
+ def create_index_with(type)
118
+ db=Neo4j.started_db
119
+ index_config = lucene_config(type)
120
+ db.lucene.node_index("#{@index_name}-#{type}", index_config)
121
+ end
122
+
123
+
124
+ # ------------------------------------------------------------------
125
+ # Event Handling
126
+
127
+ def include_trigger(clazz)
128
+ @triggered_by << clazz.to_s unless @triggered_by.include?(clazz.to_s)
129
+ end
130
+
131
+ def trigger?(classname)
132
+ @triggered_by.include?(classname || 'Neo4j::Node')
133
+ end
134
+
135
+ def on_node_created(node)
136
+ return unless trigger?(node['_classname'])
137
+ @field_types.keys.each {|field| add_index(node, field, node[field]) if node.property?(field)}
138
+ end
139
+
140
+ def on_node_deleted(node, old_props)
141
+ return unless @triggered_by.include?(old_props['_classname'] || 'Neo4j::Node')
142
+ @field_types.keys.each {|field| rm_index(node, field, old_props[field]) if old_props[field]}
143
+ end
144
+
145
+ def on_property_changed(node, field, old_val, new_val)
146
+ return unless trigger?(node[:_classname]) && @field_types.include?(field)
147
+
148
+ rm_index(node, field, old_val) if old_val
149
+
150
+ # add index
151
+ add_index(node, field, new_val) if new_val
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+ end