neo4j 1.0.0.beta.13 → 1.0.0.beta.14

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.
@@ -1,6 +1,9 @@
1
1
  module Neo4j
2
2
  module Property
3
3
 
4
+ # Returns a hash of all properties
5
+ # It also include the id of the node with the key <tt>_neo_id</tt>
6
+ #
4
7
  def props
5
8
  ret = {"_neo_id" => neo_id}
6
9
  iter = getPropertyKeys.iterator
@@ -11,16 +14,24 @@ module Neo4j
11
14
  ret
12
15
  end
13
16
 
17
+ # Returns the unique id of this node.
18
+ # Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span:
19
+ # if the node is deleted, it's likely that a new node at some point will get the old id. Note:
20
+ # this makes node ids brittle as public APIs.
14
21
  def neo_id
15
22
  getId
16
23
  end
17
24
 
25
+ # Returns a hash of properties with keys not starting with <tt>_</tt>
26
+ # That means that the neo_id will not be included in the returned hash.
27
+ #
18
28
  def attributes
19
29
  attr = props
20
30
  attr.keys.each { |k| attr.delete k if k[0] == ?_ }
21
31
  attr
22
32
  end
23
33
 
34
+ # Checks if the given key exist as a property.
24
35
  def property?(key)
25
36
  has_property?(key.to_s)
26
37
  end
@@ -29,11 +40,11 @@ module Neo4j
29
40
  # If the option <code>{:strict => true}</code> is given, any properties present on
30
41
  # the node but not present in the hash will be removed from the node.
31
42
  #
32
- # === Parameters
33
- # struct_or_hash<#each_pair>:: the key and value to be set, should respond to 'each_pair'
43
+ # ==== Parameters
44
+ # struct_or_hash:: the key and value to be set, should respond to <tt>each_pair</tt>
34
45
  # options:: further options defining the context of the update, should be a Hash
35
46
  #
36
- # === Returns
47
+ # ==== Returns
37
48
  # self
38
49
  #
39
50
  def update(struct_or_hash, options={})
@@ -54,11 +65,16 @@ module Neo4j
54
65
  self
55
66
  end
56
67
 
68
+
69
+ # Returns the value of the given key or nil if the property does not exist.
57
70
  def [](key)
58
71
  return unless property?(key)
59
72
  get_property(key.to_s)
60
73
  end
61
74
 
75
+ # Sets the property of this node.
76
+ # Property keys are always strings. Valid property value types are the primitives(<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>Boolean</tt>), and arrays of those primitives.
77
+ #
62
78
  def []=(key, value)
63
79
  k = key.to_s
64
80
  if value.nil?
@@ -10,7 +10,6 @@ module Neo4j
10
10
  extend ActiveModel::Callbacks
11
11
  extend Neo4j::Validations::ClassMethods
12
12
  extend TxMethods
13
- # extend ClassMethods::Relationship
14
13
 
15
14
  define_model_callbacks :create, :save, :update, :destroy
16
15
 
@@ -24,9 +24,9 @@ module Neo4j::Rails
24
24
  outgoing(java_type.name).new(other_java_node)
25
25
  end
26
26
 
27
- def getSingleRelationship(type, dir)
27
+ def rel(dir, type)
28
28
  # TODO incoming not implemented, needed ?
29
- @outgoing_rels[type.name] && @outgoing_rels[type.name].rels.first
29
+ @outgoing_rels[type.to_s] && @outgoing_rels[type.to_s].rels.first
30
30
  end
31
31
 
32
32
  def getRelationships(*args)
@@ -4,6 +4,11 @@ module Neo4j
4
4
  include Neo4j::Property
5
5
  include Neo4j::Equal
6
6
 
7
+ alias_method :_end_node, :getEndNode
8
+ alias_method :_start_node, :getStartNode
9
+ alias_method :_other_node, :getOtherNode
10
+
11
+
7
12
  def del
8
13
  delete
9
14
  end
@@ -39,6 +44,17 @@ module Neo4j
39
44
  end
40
45
 
41
46
 
47
+ # Returns the relationship name
48
+ #
49
+ # ====Example
50
+ # a = Neo4j::Node.new
51
+ # a.outgoing(:friends) << Neo4j::Node.new
52
+ # a.rels.first.rel_type # => 'friends'
53
+ #
54
+ def rel_type
55
+ getType().name()
56
+ end
57
+
42
58
  def class
43
59
  Neo4j::Relationship
44
60
  end
@@ -15,6 +15,16 @@ module Neo4j
15
15
  @dir = dir_to_java(dir)
16
16
  end
17
17
 
18
+ def to_s
19
+ if @type
20
+ "#{self.class} [type: #{@type} dir:#{@dir}]"
21
+ elsif @types
22
+ "#{self.class} [types: #{@types.join(',')} dir:#{@dir}]"
23
+ else
24
+ "#{self.class} [types: ANY dir:#{@dir}]"
25
+ end
26
+ end
27
+
18
28
  def each
19
29
  iterator.each {|i| yield i.wrapper}
20
30
  end
data/lib/neo4j/to_java.rb CHANGED
@@ -14,4 +14,18 @@ module Neo4j
14
14
  end
15
15
  end
16
16
  end
17
- end
17
+ end
18
+
19
+
20
+ org.neo4j.kernel.impl.core.IntArrayIterator.class_eval do
21
+ def each_wrapped
22
+ while(hasNext())
23
+ yield self.next().wrapper
24
+ end
25
+ end
26
+
27
+ def wrapped
28
+ Enumerator.new(self, :each_wrapped)
29
+ end
30
+
31
+ end
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = "1.0.0.beta.13"
2
+ VERSION = "1.0.0.beta.14"
3
3
  end
data/neo4j.gemspec CHANGED
@@ -13,18 +13,18 @@ Gem::Specification.new do |s|
13
13
  s.homepage = "http://github.com/andreasronge/neo4j/tree"
14
14
  s.rubyforge_project = 'neo4j'
15
15
  s.summary = "A graph database for JRuby"
16
- s.description = s.summary
16
+ s.description = <<-EOF
17
+ You can think of Neo4j as a high-performance graph engine with all the features of a mature and robust database.
18
+ The programmer works with an object-oriented, flexible network structure rather than with strict and static tables — yet enjoys all the benefits of a fully transactional, enterprise-strength database.
19
+ It comes included with the Apache Lucene document database.
20
+ EOF
21
+
17
22
  s.require_path = 'lib'
18
23
  s.files = Dir.glob("{bin,lib}/**/*") + %w(README.rdoc CHANGELOG CONTRIBUTORS Gemfile neo4j.gemspec)
19
24
  s.has_rdoc = true
20
25
  s.extra_rdoc_files = %w( README.rdoc )
21
26
  s.rdoc_options = ["--quiet", "--title", "Neo4j.rb", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
22
27
  s.required_ruby_version = ">= 1.8.7"
23
- s.add_dependency("activemodel", ["~> 3.0.0"])
24
- s.add_dependency("railties", ["~> 3.0.0"])
25
- s.add_development_dependency "rspec-apigen", ">= 0.0.4"
26
- s.add_development_dependency "rspec", ">= 2.0.0.beta.20"
27
- s.add_development_dependency "rspec-rails-matchers", "= 0.2.1"
28
-
29
- # s.add_development_dependency "rspec-unit", ">= 0.0.1"
28
+ s.add_dependency("activemodel", ">= 3.0.0")
29
+ s.add_dependency("railties", ">= 3.0.0")
30
30
  end
metadata CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
7
7
  - 0
8
8
  - 0
9
9
  - beta
10
- - 13
11
- version: 1.0.0.beta.13
10
+ - 14
11
+ version: 1.0.0.beta.14
12
12
  platform: ruby
13
13
  authors:
14
14
  - Andreas Ronge
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-12 00:00:00 +02:00
19
+ date: 2010-10-22 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -24,7 +24,7 @@ dependencies:
24
24
  prerelease: false
25
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  segments:
30
30
  - 3
@@ -38,7 +38,7 @@ dependencies:
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - ~>
41
+ - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  segments:
44
44
  - 3
@@ -47,51 +47,9 @@ dependencies:
47
47
  version: 3.0.0
48
48
  type: :runtime
49
49
  version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: rspec-apigen
52
- prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- segments:
58
- - 0
59
- - 0
60
- - 4
61
- version: 0.0.4
62
- type: :development
63
- version_requirements: *id003
64
- - !ruby/object:Gem::Dependency
65
- name: rspec
66
- prerelease: false
67
- requirement: &id004 !ruby/object:Gem::Requirement
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- segments:
72
- - 2
73
- - 0
74
- - 0
75
- - beta
76
- - 20
77
- version: 2.0.0.beta.20
78
- type: :development
79
- version_requirements: *id004
80
- - !ruby/object:Gem::Dependency
81
- name: rspec-rails-matchers
82
- prerelease: false
83
- requirement: &id005 !ruby/object:Gem::Requirement
84
- requirements:
85
- - - "="
86
- - !ruby/object:Gem::Version
87
- segments:
88
- - 0
89
- - 2
90
- - 1
91
- version: 0.2.1
92
- type: :development
93
- version_requirements: *id005
94
- description: A graph database for JRuby
50
+ description: "You can think of Neo4j as a high-performance graph engine with all the features of a mature and robust database.\n\
51
+ The programmer works with an object-oriented, flexible network structure rather than with strict and static tables \xE2\x80\x94 yet enjoys all the benefits of a fully transactional, enterprise-strength database.\n\
52
+ It comes included with the Apache Lucene document database.\n"
95
53
  email: andreas.ronge@gmail.com
96
54
  executables: []
97
55
 
@@ -114,7 +72,6 @@ files:
114
72
  - lib/neo4j/relationship_mixin.rb
115
73
  - lib/neo4j/load.rb
116
74
  - lib/neo4j/database.rb
117
- - lib/neo4j/index.rb
118
75
  - lib/neo4j/version.rb
119
76
  - lib/neo4j/node_relationship.rb
120
77
  - lib/neo4j/equal.rb
@@ -142,6 +99,11 @@ files:
142
99
  - lib/neo4j/mapping/class_methods/root.rb
143
100
  - lib/neo4j/mapping/class_methods/init_rel.rb
144
101
  - lib/neo4j/mapping/class_methods/relationship.rb
102
+ - lib/neo4j/index/index_registry.rb
103
+ - lib/neo4j/index/wrapped_query.rb
104
+ - lib/neo4j/index/indexer.rb
105
+ - lib/neo4j/index/class_methods.rb
106
+ - lib/neo4j/index/index.rb
145
107
  - README.rdoc
146
108
  - CHANGELOG
147
109
  - CONTRIBUTORS
data/lib/neo4j/index.rb DELETED
@@ -1,248 +0,0 @@
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, :index_type_for, :index_name
16
-
17
-
18
- # Sets which indexer should be used for the given node class
19
- # Returns the old one if there was an old indexer.
20
- def node_indexer(clazz)
21
- indexer(clazz, :node)
22
- end
23
-
24
- # Sets which indexer should be used for the given relationship class
25
- # Returns the old one if there was an old indexer.
26
- def rel_indexer(clazz)
27
- indexer(clazz, :rel)
28
- end
29
-
30
- def indexer(clazz, type) #:nodoc:
31
- old = @indexer
32
- @@indexers ||= {}
33
- if @@indexers.include?(clazz)
34
- # we want to reuse an existing index
35
- @indexer = @@indexers[clazz]
36
- @indexer.include_trigger(self)
37
- else
38
- @indexer = Indexer.new(clazz, type)
39
- @@indexers[clazz] = @indexer
40
- end
41
- old
42
- end
43
- end
44
-
45
- class WrappedQuery
46
- include Enumerable
47
-
48
- def initialize(index, query)
49
- @index = index
50
- @query = query
51
- end
52
-
53
- def each
54
- hits.each{|n| yield n.wrapper}
55
- end
56
-
57
- def close
58
- @hits.close if @hits
59
- end
60
-
61
- def empty?
62
- hits.size == 0
63
- end
64
-
65
- def size
66
- hits.size
67
- end
68
-
69
- def hits
70
- @hits ||= perform_query
71
- end
72
-
73
- def desc(*fields)
74
- @order = fields.inject(@order || {}){|memo, field| memo[field] = true; memo}
75
- self
76
- end
77
-
78
- def asc(*fields)
79
- @order = fields.inject(@order || {}){|memo, field| memo[field] = false; memo}
80
- self
81
- end
82
-
83
- def perform_query
84
- if @order
85
- java_sort_fields = @order.keys.inject([]) do |memo, field|
86
- memo << org.apache.lucene.search.SortField.new(field.to_s, org.apache.lucene.search.SortField::STRING, @order[field])
87
- end
88
- sort = org.apache.lucene.search.Sort.new(*java_sort_fields)
89
- @query = org.neo4j.index.impl.lucene.QueryContext.new(@query).sort(sort)
90
- end
91
- @index.query(@query)
92
- end
93
- end
94
-
95
- class Indexer
96
- attr_reader :index_name
97
-
98
- def initialize(clazz, type)
99
- @index_name = clazz.to_s
100
-
101
- # do we want to index nodes or relationships ?
102
- @type = type
103
-
104
- @indexes = {} # key = type, value = java neo4j index
105
- @field_types = {} # key = field, value = type (e.g. :exact or :fulltext)
106
- @triggered_by = clazz.to_s
107
- end
108
-
109
- # add an index on a field that will be automatically updated by events.
110
- def index(field, conf = {})
111
- type = conf[:type] || :exact
112
- @field_types[field.to_s] = type
113
- Neo4j.default_db.event_handler.add(self)
114
- end
115
-
116
- def index?(field)
117
- @field_types.include?(field.to_s)
118
- end
119
-
120
- def index_type_for(field)
121
- return nil unless index?(field)
122
- @field_types[field.to_s]
123
- end
124
-
125
- def index_type?(type)
126
- @field_types.values.include?(type)
127
- end
128
-
129
- def add_index(entity, field, value)
130
- index_for_field(field.to_s).add(entity, field, value)
131
- end
132
-
133
- def rm_index(entity, field, value)
134
- index_for_field(field).remove(entity, field, value)
135
- end
136
-
137
- def find(query, params = {})
138
- type = params[:type] || :exact
139
- index = index_for_type(type)
140
- query = (params[:wrapped].nil? || params[:wrapped]) ? WrappedQuery.new(index, query) : index.query(query)
141
-
142
- if block_given?
143
- begin
144
- ret = yield query
145
- ensure
146
- query.close
147
- end
148
- ret
149
- else
150
- query
151
- end
152
- end
153
-
154
- # clears the index, if no type is provided clear all types of indexes
155
- def clear_index_type(type=nil)
156
- if type
157
- #raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
158
- @indexes[type] && @indexes[type].clear
159
- else
160
- @indexes.each_value{|index| index.clear}
161
- end
162
- end
163
-
164
- def rm_index_type(type=nil)
165
- if type
166
- #raise "can't remove index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
167
- @field_types.delete_if {|k,v| v == type}
168
- else
169
- @field_types.clear
170
- end
171
- end
172
-
173
- def index_for_field(field)
174
- type = @field_types[field]
175
- @indexes[type] ||= create_index_with(type)
176
- end
177
-
178
- def index_for_type(type)
179
- @indexes[type] ||= create_index_with(type)
180
- end
181
-
182
- def lucene_config(type)
183
- conf = Neo4j::Config[:lucene][type.to_sym]
184
- raise "unknown lucene type #{type}" unless conf
185
- conf
186
- end
187
-
188
- def create_index_with(type)
189
- db=Neo4j.started_db
190
- index_config = lucene_config(type)
191
- if @type == :node
192
- db.lucene.node_index("#{@index_name}-#{type}", index_config)
193
- else
194
- db.lucene.relationship_index("#{@index_name}-#{type}", index_config)
195
- end
196
- end
197
-
198
-
199
- # ------------------------------------------------------------------
200
- # Event Handling
201
-
202
- def include_trigger(clazz)
203
- @triggered_by << clazz.to_s unless @triggered_by.include?(clazz.to_s)
204
- end
205
-
206
- def trigger?(classname)
207
- @triggered_by.include?(classname || (@type==:node ? 'Neo4j::Node' : 'Neo4j::Relationship'))
208
- end
209
-
210
- def on_node_created(node)
211
- return unless trigger?(node['_classname'])
212
- @field_types.keys.each {|field| add_index(node, field, node[field]) if node.property?(field)}
213
- end
214
-
215
- def on_node_deleted(node, old_props)
216
- return unless trigger?(old_props['_classname'])
217
- @field_types.keys.each {|field| rm_index(node, field, old_props[field]) if old_props[field]}
218
- end
219
-
220
- def on_property_changed(node, field, old_val, new_val)
221
- return unless trigger?(node[:_classname]) && @field_types.include?(field)
222
-
223
- rm_index(node, field, old_val) if old_val
224
-
225
- # add index
226
- add_index(node, field, new_val) if new_val
227
- end
228
-
229
- def on_rel_property_changed(rel, field, old_val, new_val)
230
- # works exactly like for nodes
231
- on_property_changed(rel, field, old_val, new_val)
232
- end
233
-
234
- def on_relationship_created(rel)
235
- # works exactly like for nodes
236
- on_node_created(rel)
237
- end
238
-
239
- def on_relationship_deleted(rel, old_props)
240
- # works exactly like for nodes
241
- on_node_deleted(rel, old_props)
242
- end
243
-
244
- end
245
-
246
- end
247
-
248
- end