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,72 @@
1
+ module Neo4j
2
+ module Property
3
+
4
+ def props
5
+ ret = {"_neo_id" => neo_id}
6
+ iter = getPropertyKeys.iterator
7
+ while (iter.hasNext) do
8
+ key = iter.next
9
+ ret[key] = get_property(key)
10
+ end
11
+ ret
12
+ end
13
+
14
+ def neo_id
15
+ getId
16
+ end
17
+
18
+ def attributes
19
+ attr = props
20
+ attr.keys.each { |k| attr.delete k if k[0] == ?_ }
21
+ attr
22
+ end
23
+
24
+ def property?(key)
25
+ has_property?(key.to_s)
26
+ end
27
+
28
+ # Updates this node/relationship's properties by using the provided struct/hash.
29
+ # If the option <code>{:strict => true}</code> is given, any properties present on
30
+ # the node but not present in the hash will be removed from the node.
31
+ #
32
+ # === Parameters
33
+ # struct_or_hash<#each_pair>:: the key and value to be set, should respond to 'each_pair'
34
+ # options:: further options defining the context of the update, should be a Hash
35
+ #
36
+ # === Returns
37
+ # self
38
+ #
39
+ def update(struct_or_hash, options={})
40
+ strict = options[:strict]
41
+ keys_to_delete = props.keys - %w(_neo_id _classname) if strict
42
+ struct_or_hash.each_pair do |key, value|
43
+ next if %w(_neo_id _classname).include? key.to_s
44
+ # do not allow special properties to be mass assigned
45
+ keys_to_delete.delete(key) if strict
46
+ setter_meth = "#{key}=".to_sym
47
+ if @_wrapper && @_wrapper.respond_to?(setter_meth)
48
+ @_wrapper.send(setter_meth, value)
49
+ else
50
+ self[key] = value
51
+ end
52
+ end
53
+ keys_to_delete.each { |key| delete_property(key) } if strict
54
+ self
55
+ end
56
+
57
+ def [](key)
58
+ return unless property?(key)
59
+ get_property(key.to_s)
60
+ end
61
+
62
+ def []=(key, value)
63
+ k = key.to_s
64
+ if value.nil?
65
+ remove_property(k)
66
+ else
67
+ set_property(k, value)
68
+ end
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,19 @@
1
+ module Neo4j
2
+ module Rails
3
+ class LuceneConnectionCloser
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ @app.call(env)
10
+ ensure
11
+ Thread.current[:neo4j_lucene_connection].each {|hits| hits.close} if Thread.current[:neo4j_lucene_connection]
12
+ Thread.current[:neo4j_lucene_connection] = nil
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ Thread.current
@@ -0,0 +1,210 @@
1
+ class Neo4j::Model
2
+ include Neo4j::NodeMixin
3
+ include ActiveModel::Validations
4
+ include ActiveModel::Dirty
5
+ extend ActiveModel::Naming
6
+ extend ActiveModel::Callbacks
7
+ define_model_callbacks :create, :save, :update, :destroy
8
+
9
+ class RecordInvalidError < RuntimeError
10
+ attr_reader :record
11
+
12
+ def initialize(record)
13
+ @record = record
14
+ super(@record.errors.full_messages.join(", "))
15
+ end
16
+ end
17
+
18
+ # --------------------------------------
19
+ # Initialize
20
+ # --------------------------------------
21
+
22
+ def initialize(*)
23
+ end
24
+
25
+ def init_on_create(*args) # :nodoc:
26
+ _run_create_callbacks do
27
+ @_new_record = true
28
+ super
29
+ end
30
+ end
31
+
32
+ # --------------------------------------
33
+ # Identity
34
+ # --------------------------------------
35
+
36
+ def id
37
+ self.neo_id
38
+ end
39
+
40
+ def to_param
41
+ persisted? ? neo_id.to_s : nil
42
+ end
43
+
44
+ # Returns an Enumerable of all (primary) key attributes
45
+ # or nil if model.persisted? is false
46
+ def to_key
47
+ persisted? ? [:id] : nil
48
+ end
49
+
50
+
51
+ # --------------------------------------
52
+ # enables ActiveModel::Dirty and Validation
53
+ # --------------------------------------
54
+
55
+ def method_missing(method_id, *args, &block)
56
+ if !self.class.attribute_methods_generated?
57
+ self.class.define_attribute_methods(self.class.properties_info.keys)
58
+ # try again
59
+ send(method_id, *args, &block)
60
+ end
61
+ end
62
+
63
+ # redefine this methods so that ActiveModel::Dirty will work
64
+ def []=(key, new_value)
65
+ key = key.to_s
66
+ unless key[0] == ?_
67
+ old_value = self.send(:[], key)
68
+ attribute_will_change!(key) unless old_value == new_value
69
+ #changed_attributes[key] = new_value unless old_value == new_value
70
+ end
71
+ super
72
+ end
73
+
74
+ def attribute_will_change!(attr)
75
+ begin
76
+ value = __send__(:[], attr)
77
+ value = value.duplicable? ? value.clone : value
78
+ rescue TypeError, NoMethodError
79
+ end
80
+ changed_attributes[attr] = value
81
+ end
82
+
83
+
84
+ def read_attribute_for_validation(key)
85
+ self[key]
86
+ end
87
+
88
+ def attributes=(attrs)
89
+ attrs.each do |k, v|
90
+ if respond_to?("#{k}=")
91
+ send("#{k}=", v)
92
+ else
93
+ self[k] = v
94
+ end
95
+ end
96
+ end
97
+
98
+
99
+ # Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved.
100
+ # If the saving fails because of a connection or remote service error, an exception will be raised.
101
+ # If saving fails because the resource is invalid then false will be returned.
102
+ def update_attributes(attributes)
103
+ update(attributes) # TODO !!!
104
+ save
105
+ end
106
+
107
+ # --------------------------------------
108
+ # CRUD
109
+ # --------------------------------------
110
+
111
+ def delete
112
+ super
113
+ @_deleted = true
114
+ end
115
+
116
+ def save
117
+ if valid?
118
+ # if we are trying to save a value then we should create a real node
119
+ if persisted?
120
+ _run_update_callbacks do
121
+ @previously_changed = changes
122
+ @changed_attributes.clear
123
+ end
124
+ else
125
+ node = Neo4j::Node.new(props)
126
+ init_on_load(node)
127
+ init_on_create
128
+ @previously_changed = changes
129
+ @changed_attributes.clear
130
+ end
131
+ true
132
+ end
133
+ end
134
+
135
+ def save!
136
+ raise RecordInvalidError.new(self) unless save
137
+ end
138
+
139
+ # In neo4j all object are automatically persisted in the database when created (but the Transaction might get rollback)
140
+ # Only the Neo4j::Value object will never exist in the database
141
+ def persisted?
142
+ !_java_node.kind_of?(Neo4j::Value)
143
+ end
144
+
145
+ def to_model
146
+ self
147
+ end
148
+
149
+ def new_record?()
150
+ @_new_record
151
+ end
152
+
153
+ def del
154
+ @_deleted = true
155
+ super
156
+ end
157
+
158
+ def destroy
159
+ _run_update_callbacks { del }
160
+ end
161
+
162
+ def destroyed?()
163
+ @_deleted
164
+ end
165
+
166
+
167
+ # --------------------------------------
168
+ # Class Methods
169
+ # --------------------------------------
170
+
171
+ class << self
172
+ # returns a value object instead of creating a new node
173
+ def new(*args)
174
+ value = Neo4j::Value.new(*args)
175
+ wrapped = self.orig_new
176
+ wrapped.init_on_load(value)
177
+ wrapped
178
+ end
179
+
180
+
181
+ # Handle Model.find(params[:id])
182
+ def find(*args)
183
+ if args.length == 1 && String === args[0] && args[0].to_i != 0
184
+ load(*args)
185
+ else
186
+ hits = super
187
+ # We need to save this so that the Rack Neo4j::Rails:LuceneConnection::Closer can close it
188
+ Thread.current[:neo4j_lucene_connection] ||= []
189
+ Thread.current[:neo4j_lucene_connection] << hits
190
+ hits
191
+ end
192
+ end
193
+
194
+ def load(*ids)
195
+ result = ids.map { |id| Neo4j::Node.load(id) }
196
+ if ids.length == 1
197
+ result.first
198
+ else
199
+ result
200
+ end
201
+ end
202
+
203
+ def create!(*args)
204
+ model = create(*args)
205
+ raise RecordInvalidError.new(model) unless model.valid?
206
+ model
207
+ end
208
+ end
209
+
210
+ end
@@ -0,0 +1,16 @@
1
+ module Neo4j
2
+ class Railtie < ::Rails::Railtie
3
+ config.neo4j = ActiveSupport::OrderedOptions.new
4
+
5
+ initializer "neo4j.tx" do |app|
6
+ app.config.middleware.use Neo4j::Rails::LuceneConnectionCloser
7
+ end
8
+
9
+ # Starting Neo after :load_config_initializers allows apps to
10
+ # register migrations in config/initializers
11
+ initializer "neo4j.start", :after => :load_config_initializers do |app|
12
+ Neo4j::Config.setup.merge!(app.config.neo4j.to_hash)
13
+ Neo4j.start
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module Neo4j
2
+ module Rails
3
+
4
+ # This method is typically used in an Rails ActionController as a filter method.
5
+ # It will guarantee that an transaction is create before your action is called,
6
+ # and that the transaction is finished after your action is called.
7
+ #
8
+ # Example:
9
+ # class MyController < ActionController::Base
10
+ # around_filter Neo4j::Rails::Transaction, :only => [:edit, :delete]
11
+ # ...
12
+ # end
13
+ class Transaction
14
+ def self.filter(*)
15
+ begin
16
+ tx = Neo4j::Transaction.new
17
+ yield
18
+ tx.success
19
+ rescue Exception
20
+ tx.failure unless tx.nil?
21
+ raise
22
+ ensure
23
+ tx.finish unless tx.nil?
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,43 @@
1
+ module Neo4j
2
+
3
+ class Value
4
+ include Neo4j::Property
5
+ include org.neo4j.graphdb.Node
6
+
7
+ def initialize(*args)
8
+ # the first argument can be an hash of properties to set
9
+ @props = {}
10
+ if args[0].respond_to?(:each_pair)
11
+ args[0].each_pair { |k, v| set_property(k.to_s, v) }
12
+ end
13
+ end
14
+
15
+ # override Neo4j::Property#props
16
+ def props
17
+ @props
18
+ end
19
+
20
+ def getId
21
+ nil
22
+ end
23
+
24
+ # Pretend this object is a Java Node
25
+ def has_property?(key)
26
+ !@props[key].nil?
27
+ end
28
+
29
+ def set_property(key,value)
30
+ @props[key] = value
31
+ end
32
+
33
+ def get_property(key)
34
+ @props[key]
35
+ end
36
+
37
+ def remove_property(key)
38
+ @props.delete(key)
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,88 @@
1
+ module Neo4j
2
+
3
+ org.neo4j.kernel.impl.core.RelationshipProxy.class_eval do
4
+ include Neo4j::Property
5
+ include Neo4j::Equal
6
+
7
+ def del
8
+ delete
9
+ end
10
+
11
+ def end_node # :nodoc:
12
+ Neo4j::Node.load_wrapper(getEndNode)
13
+ end
14
+
15
+ def start_node # :nodoc:
16
+ Neo4j::Node.load_wrapper(getStartNode)
17
+ end
18
+
19
+ def other_node(node) # :nodoc:
20
+ java_node = node.respond_to?(:_java_node)? node._java_node : node
21
+ other_node = getOtherNode(java_node)
22
+ Neo4j::Node.load_wrapper(other_node)
23
+ end
24
+ end
25
+
26
+ #
27
+ # A relationship between two nodes in the graph. A relationship has a start node, an end node and a type.
28
+ # You can attach properties to relationships with the API specified in Neo4j::JavaPropertyMixin.
29
+ #
30
+ # Relationship are created by invoking the << operator on the rels method on the node as follow:
31
+ # node.outgoing(:friends) << other_node << yet_another_node
32
+ #
33
+ # or using the Neo4j::Relationship#new method (which does the same thing):
34
+ # rel = Neo4j::Relationship.new(:friends, node, other_node)
35
+ #
36
+ # The fact that the relationship API gives meaning to start and end nodes implicitly means that all relationships have a direction.
37
+ # In the example above, rel would be directed from node to otherNode.
38
+ # A relationship's start node and end node and their relation to outgoing and incoming are defined so that the assertions in the following code are true:
39
+ #
40
+ # a = Neo4j::Node.new
41
+ # b = Neo4j::Node.new
42
+ # rel = Neo4j::Relationship.new(:some_type, a, b)
43
+ # # Now we have: (a) --- REL_TYPE ---> (b)
44
+ #
45
+ # rel.start_node # => a
46
+ # rel.end_node # => b
47
+ #
48
+ # Furthermore, Neo4j guarantees that a relationship is never "hanging freely,"
49
+ # i.e. start_node, end_node and other_node are guaranteed to always return valid, non-null nodes.
50
+ #
51
+ # See also the Neo4j::RelationshipMixin if you want to wrap a relationship with your own Ruby class.
52
+ #
53
+ # === Included Mixins
54
+ # * Neo4j::Property
55
+ # * Neo4j::Equal
56
+ #
57
+ # (Those mixin are actually not included in the Neo4j::Relationship but instead directly included in the java class org.neo4j.kernel.impl.core.RelationshipProxy)
58
+ #
59
+ class Relationship
60
+ class << self
61
+ # Returns a org.neo4j.graphdb.Relationship java object (!)
62
+ # Will trigger a event that the relationship was created.
63
+ #
64
+ # === Parameters
65
+ # type :: the type of relationship
66
+ # from_node :: the start node of this relationship
67
+ # end_node :: the end node of this relationship
68
+ # props :: optional properties for the created relationship
69
+ #
70
+ # === Returns
71
+ # org.neo4j.graphdb.Relationship java object
72
+ #
73
+ # === Examples
74
+ #
75
+ # Neo4j::Relationship.new :friend, node1, node2, :since => '2001-01-02', :status => 'okey'
76
+ #
77
+ def new(type, from_node, to_node, props={})
78
+ rel = from_node.outgoing(type).new(to_node)
79
+ props.each_pair {|k,v| rel[k] = v}
80
+ rel
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+