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,60 @@
1
+ # This is a mixin that is used to extend the java object org.neo4j.graphdb.Relationship
2
+ #
3
+ module Neo4j::JavaRelationshipMixin
4
+
5
+ # Deletes this relationship.
6
+ #
7
+ def del
8
+ Neo4j.event_handler.relationship_deleted(wrapper)
9
+ type = getType().name()
10
+
11
+ delete
12
+
13
+ if end_node.class.respond_to?(:indexer)
14
+ end_node.class.indexer.on_relationship_deleted(end_node, type)
15
+ elsif end_node.wrapper?
16
+ end_node.wrapper_class.indexer.on_relationship_deleted(end_node.wrapper, type)
17
+ end
18
+ end
19
+
20
+ # Returns the end node of this relationship
21
+ def end_node
22
+ id = getEndNode.getId
23
+ Neo4j.load_node(id)
24
+ end
25
+
26
+ # Returns the start node of this relationship
27
+ def start_node
28
+ id = getStartNode.getId
29
+ Neo4j.load_node(id)
30
+ end
31
+
32
+ # A convenience operation that, given a node that is attached to this relationship, returns the other node.
33
+ # For example if node is a start node, the end node will be returned, and vice versa.
34
+ # This is a very convenient operation when you're manually traversing the node space by invoking one of the #rels operations on node.
35
+ #
36
+ # This operation will throw a runtime exception if node is neither this relationship's start node nor its end node.
37
+ #
38
+ # ==== Example
39
+ # For example, to get the node "at the other end" of a relationship, use the following:
40
+ # Node endNode = node.rel(:some_rel_type).other_node(node)
41
+ #
42
+ def other_node(node)
43
+ neo_node = node
44
+ neo_node = node._java_node if node.respond_to?(:_java_node)
45
+ id = getOtherNode(neo_node).getId
46
+ Neo4j.load_node(id)
47
+ end
48
+
49
+
50
+ # Returns the neo relationship type that this relationship is used in.
51
+ # (see java API org.neo4j.graphdb.Relationship#getType and org.neo4j.graphdb.RelationshipType)
52
+ #
53
+ # ==== Returns
54
+ # the relationship type (of type Symbol)
55
+ #
56
+ def relationship_type
57
+ get_type.name.to_sym
58
+ end
59
+
60
+ end
@@ -0,0 +1,157 @@
1
+ module Neo4j
2
+
3
+
4
+ # By including this mixing on a node class one can add migrations to it.
5
+ # Adds a db_version attribute on the class including this mixin.
6
+ #
7
+ module MigrationMixin
8
+
9
+ # Returns the current version of the database of the class including this Mixin.
10
+ #
11
+ def db_version
12
+ Neo4j::Transaction.run {self[:db_version] || 0}
13
+ end
14
+
15
+
16
+ # Force one or more migrations to occur if not already done yet.
17
+ # Will check the current db_version with the given 'to_version' and perform
18
+ # migrations. If the 'to_version' parameter is not given then it will upgrade the
19
+ # database with all migrations it can find.
20
+ #
21
+ # === Parameters
22
+ # to_version:: the version we want to migrate to, if not given then all migrations will be run
23
+ # verbose:: if it should print out information of which migration is run
24
+ #
25
+ def migrate!(to_version=nil, verbose = false)
26
+ return if self.class.migrations.nil? || self.class.migrations.empty?
27
+
28
+
29
+ # which version should we go to if to_version was not provided ?
30
+ to_version ||= self.class.migrations.keys.sort.reverse[0]
31
+ puts "Migration: Curr ver #{db_version} need upgrade to version #{to_version}" if verbose
32
+
33
+ # do we need to migrate ?
34
+ return if db_version == to_version
35
+
36
+ # ok, so we are running some migrations
37
+ if (db_version < to_version)
38
+ upgrade( (db_version+1).upto(to_version).collect { |ver| self.class.migrations[ver] }, verbose )
39
+ else
40
+ downgrade( db_version.downto(to_version+1).collect { |ver| self.class.migrations[ver] }, verbose )
41
+ end
42
+ end
43
+
44
+ # Running the up method on the given migrations.
45
+ #
46
+ # === Parameters
47
+ # migrations:: an enumerable of Migration objects
48
+ def upgrade(migrations, verbose=false)
49
+ migrations.each do |m|
50
+ puts "Running upgrade migration #{m.version} - #{m.name}" if verbose
51
+ m.up_migrator.execute(self, m.version, &m.up_block)
52
+ end
53
+ end
54
+
55
+ # Running the down method on the given migrations.
56
+ #
57
+ # === Parameters
58
+ # migrations:: an enumerable of Migration objects
59
+ def downgrade(migrations, verbose=false)
60
+ migrations.each do |m|
61
+ puts "Running downgrade migration #{m.version} - #{m.name}" if verbose
62
+ m.down_migrator.execute(self, m.version-1, &m.down_block)
63
+ end
64
+ end
65
+
66
+ def self.included(c) # :nodoc:
67
+ c.extend Neo4j::MigrationMixin::ClassMethods
68
+ end
69
+
70
+ module ClassMethods
71
+ attr_accessor :migrations, :migrate_to
72
+
73
+ # Specifies a migration to be performed.
74
+ #
75
+ # === Example
76
+ #
77
+ # In the following example the up and down method will be evaluated in the context of a Person node.
78
+ #
79
+ # Person.migration 1, :my_first_migration do
80
+ # up { ... }
81
+ # down { ... }
82
+ # end
83
+ #
84
+ # See the Neo4j::MigrationMixin::Migration which the DSL is evaluated in.
85
+ #
86
+ def migration(version, name, &block)
87
+ @migrations ||= {}
88
+ migration = Migration.new(version, name)
89
+ migration.instance_eval(&block)
90
+ @migrations[version] = migration
91
+ end
92
+
93
+ # This is used for lazy migration. It stores the version that we want to upgrade to but does not perform the migrations.
94
+ # Only when the node is being loaded from the database (Neo4j::NodeMixin#init_with_node) then
95
+ # it will check and see if one or more migration is needed to be performed.
96
+ #
97
+ def migrate!(to_version=nil)
98
+ @migrate_to = to_version
99
+ end
100
+ end
101
+
102
+ # This is the context in which the Migrations DSL are evaluated in.
103
+ class Migration < Struct.new(:version, :name)
104
+ attr_reader :up_block, :down_block, :up_migrator, :down_migrator
105
+
106
+ # Specifies a code block which is run when the migration is upgraded.
107
+ #
108
+ # === Parameters
109
+ # migrator:: Default Neo4j::MigrationMixin::Migrator - used to execute the block
110
+ def up(migrator = Migrator, &block)
111
+ @up_block = block
112
+ @up_migrator = migrator
113
+ end
114
+
115
+ # Specifies a code block which is run when the migration is upgraded.
116
+ #
117
+ # === Parameters
118
+ # migrator:: Default Neo4j::MigrationMixin::Migrator - used to execute the block
119
+ def down(migrator = Migrator, &block)
120
+ @down_block = block
121
+ @down_migrator = migrator
122
+ end
123
+
124
+ def to_s
125
+ "Migration version: #{version}, name: #{name}"
126
+ end
127
+ end
128
+
129
+ # Responsible for running a migration
130
+ class Migrator
131
+ class << self
132
+ # Runs given migration block. If successful it will set the property
133
+ # ':db_version' on the given context.
134
+ #
135
+ # === Parameters
136
+ # context:: the context on which the block is evaluated in
137
+ # version:: optional, if given then will set the property db_version on the context
138
+ def execute(context, version=nil, &block)
139
+ context.instance_eval &block
140
+ Neo4j::Transaction.run { context[:db_version] = version} if version
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+
147
+ # Overrides the init method so that it will check if any migration is needed.
148
+ # Migration might take place when the node is loaded.
149
+ #
150
+ module LazyMigrationMixin
151
+ def init_with_node(java_node) # :nodoc:
152
+ super # call Neo4j::NodeMixin#init_with_node
153
+ migrate! self.class.migrate_to # for lazy migrations
154
+ end
155
+ end
156
+ end
157
+
@@ -0,0 +1,249 @@
1
+ module Neo4j
2
+
3
+
4
+ # Represents a node in the Neo4j space.
5
+ #
6
+ # Is a wrapper around a Java Neo4j::Node (org.neo4j.graphdb.Node)
7
+ # The following methods are delegated to the Java Neo4j::Node
8
+ # []=, [], property?, props, update, neo_id, rels, rel?, to_param
9
+ # rel, del, list?, list, lists, print, add_rel, outgoing, incoming,
10
+ # next, prev, next=, prev=, head
11
+ #
12
+ # Those methods are defined in included mixins
13
+ # This mixin also include the class method in the
14
+ #
15
+ # === Included Mixins
16
+ # * Neo4j::JavaPropertyMixin - instance methods for properties
17
+ # * Neo4j::JavaNodeMixin - instance methods
18
+ # * Neo4j::JavaListMixin - instance methods for list methods
19
+ # * Neo4j::RelClassMethods - class methods for generating relationship accessors
20
+ # * Neo4j::PropertyClassMethods - class methods for generating property accessors
21
+ #
22
+ module NodeMixin
23
+ extend Forwardable
24
+
25
+ def_delegators :@_java_node, :[]=, :[], :property?, :props, :update, :neo_id, :rels, :rel?, :to_param,
26
+ :rel, :del, :list?, :list, :lists, :print, :print_sub, :add_rel, :outgoing, :incoming,
27
+ :add_list_item_methods, :next, :prev, :next=, :prev=, :head # used for has_list, defined in Neo4j::JavaListMixin
28
+
29
+
30
+ # --------------------------------------------------------------------------
31
+ # Initialization methods
32
+ #
33
+
34
+
35
+ # Initialize the the neo node for this instance.
36
+ # Will create a new transaction if one is not already running.
37
+ #
38
+ # Does
39
+ # * sets the neo4j property '_classname' to self.class.to_s
40
+ # * creates a neo4j node java object (in @_java_node)
41
+ # * calls init_node if that is defined in the current class.
42
+ #
43
+ # If you want to provide your own initialize method you should instead implement the
44
+ # method init_node method.
45
+ #
46
+ # === Example
47
+ #
48
+ # class MyNode
49
+ # include Neo4j::NodeMixin
50
+ #
51
+ # def init_node(name, age)
52
+ # self[:name] = name
53
+ # self[:age] = age
54
+ # end
55
+ # end
56
+ #
57
+ # node = MyNode('jimmy', 23)
58
+ # # or also possible
59
+ # node = MyNode :name => 'jimmy', :age => 12
60
+ #
61
+ # The init_node is only called when the node is created in the database.
62
+ # The initialize method is used both for to purposes:
63
+ # loading an already existing node from the Neo4j database and creating a new node in the database.
64
+ #
65
+ def initialize(*args)
66
+ # was a neo java node provided ?
67
+ if args.length == 1 && args[0].kind_of?(org.neo4j.graphdb.Node)
68
+ # yes, it was loaded from the database
69
+ init_with_node(args[0])
70
+ elsif self.respond_to?(:init_node)
71
+ # does the class provide an initialization method ?
72
+ init_without_node({})
73
+ init_node(*args)
74
+ else
75
+ # no, but maybe it had a hash of properties to initialize it with, create node
76
+ init_without_node(args[0] || {})
77
+ end
78
+ # was a block given in order to initialize the neo4j node ?
79
+ yield self if block_given?
80
+ # must call super with no arguments so that chaining of the initialize method works
81
+ super()
82
+ end
83
+
84
+
85
+ # Inits this node with the specified java neo node
86
+ #
87
+ def init_with_node(java_node) # :nodoc:
88
+ @_java_node = java_node
89
+ java_node._wrapper=self
90
+ end
91
+
92
+ # Returns the org.neo4j.graphdb.Node wrapped object
93
+ def _java_node
94
+ @_java_node
95
+ end
96
+
97
+ # Creates a new node and initialize with given properties.
98
+ #
99
+ def init_without_node(props) # :nodoc:
100
+ props[:_classname] = self.class.to_s
101
+ @_java_node = Neo4j.create_node props
102
+ update_index if props && !props.empty?
103
+ @_java_node._wrapper = self
104
+ Neo4j.event_handler.node_created(self)
105
+ end
106
+
107
+
108
+ # Since we sometimes don't know if we have a java node or a wrapped Ruby node we need this so that we
109
+ # always can call this method
110
+ def wrapper # :nodoc:
111
+ self
112
+ end
113
+
114
+
115
+ # --------------------------------------------------------------------------
116
+ # Property methods
117
+ #
118
+
119
+
120
+ # Creates a struct class containing all properties of this class.
121
+ # This value object can be used from Ruby on Rails RESTful routing.
122
+ #
123
+ # ==== Example
124
+ #
125
+ # h = Person.value_object.new
126
+ # h.name # => nil
127
+ # h.name='kalle'
128
+ # h[:name] # => 'kalle'
129
+ #
130
+ # ==== Returns
131
+ # a value object struct
132
+ #
133
+ def value_object
134
+ vo = self.class.value_object.new
135
+ vo._update(props)
136
+ vo
137
+ end
138
+
139
+
140
+ # --------------------------------------------------------------------------
141
+ # Equal and hash methods
142
+ #
143
+
144
+ def equal?(o)
145
+ eql?(o)
146
+ end
147
+
148
+ def eql?(o)
149
+ o.kind_of?(NodeMixin) && o._java_node == @_java_node
150
+ end
151
+
152
+ def ==(o)
153
+ eql?(o)
154
+ end
155
+
156
+ def hash
157
+ @_java_node.hashCode
158
+ end
159
+
160
+
161
+ # --------------------------------------------------------------------------
162
+ # Update and Delete methods
163
+ #
164
+
165
+
166
+ # Specifies which relationships should be ignored when trying to cascade delete a node.
167
+ # If a node does not have any relationships (except those specified here to ignore) it will be cascade deleted
168
+ #
169
+ def ignore_incoming_cascade_delete?(relationship) # :nodoc:
170
+ # ignore relationship with property _cascade_delete_incoming
171
+ relationship.property?(:_cascade_delete_incoming)
172
+ end
173
+
174
+ # Updates the index for this node.
175
+ # This method will be automatically called when needed
176
+ # (a property changed or a relationship was created/deleted)
177
+ #
178
+ def update_index # :nodoc:
179
+ self.class.indexer.index(self)
180
+ end
181
+
182
+ # --------------------------------------------------------------------------
183
+ # Relationship methods
184
+ #
185
+
186
+ # Returns a Neo4j::Relationships::NodeTraverser object for traversing nodes from and to this node.
187
+ # The Neo4j::Relationships::NodeTraverser is an Enumerable that returns Neo4j::NodeMixin objects.
188
+ #
189
+ # ==== Example
190
+ #
191
+ # person_node.traverse.outgoing(:friends).each { ... }
192
+ # person_node.traverse.outgoing(:friends).raw.each { }
193
+ #
194
+ # The raw false parameter means that the ruby wrapper object will not be loaded, instead the raw Java Neo4j object will be used,
195
+ # it might improve the performance.
196
+ #
197
+ def traverse(*args)
198
+ if args.empty?
199
+ Neo4j::Relationships::NodeTraverser.new(self)
200
+ else
201
+ @_java_node.traverse(*args)
202
+ end
203
+
204
+ end
205
+
206
+
207
+ # --------------------------------------------------------------------------
208
+ # Private methods
209
+ #
210
+
211
+ def _to_java_direction(dir) # :nodoc:
212
+ case dir
213
+ when :outgoing
214
+ org.neo4j.graphdb.Direction::OUTGOING
215
+ when :incoming
216
+ org.neo4j.graphdb.Direction::INCOMING
217
+ when :both
218
+ org.neo4j.graphdb.Direction::BOTH
219
+ else
220
+ raise "Unknown parameter: '#{dir}', only accept :outgoing, :incoming or :both"
221
+ end
222
+ end
223
+
224
+
225
+ # --------------------------------------------------------------------------
226
+ # Hooks
227
+ #
228
+
229
+
230
+ # Adds class methods from
231
+ #
232
+ # * Neo4j::RelClassMethods
233
+ # * Neo4j::PropertyClassMethods
234
+ #
235
+ def self.included(c) # :nodoc:
236
+ c.instance_eval do
237
+ # these constants are used in the Neo4j::RelClassMethods and Neo4j::PropertyClassMethods
238
+ # they are defined here since they should only be defined once -
239
+ # all subclasses share the same index, declared properties and index_updaters
240
+ const_set(:ROOT_CLASS, self)
241
+ const_set(:DECL_RELATIONSHIPS, {})
242
+ const_set(:PROPERTIES_INFO, {})
243
+ end unless c.const_defined?(:DECL_RELATIONSHIPS)
244
+
245
+ c.extend Neo4j::RelClassMethods
246
+ c.extend Neo4j::PropertyClassMethods
247
+ end
248
+ end
249
+ end