neo4j-core 0.0.13-java → 0.0.14-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -93,6 +93,8 @@ module Neo4j
93
93
  delegate :rm_index
94
94
  delegate :index_type
95
95
  delegate :index_name_for_type
96
+ delegate :index_for_type
97
+ delegate :put_if_absent
96
98
  end
97
99
 
98
100
 
@@ -2,7 +2,7 @@ module Neo4j
2
2
  module Core
3
3
 
4
4
  # A mixin which adds indexing behaviour to your own Ruby class
5
- # You are expected to implement the method `java_entity` returning the underlying Neo4j Node or Relationship.
5
+ # You are expected to implement the method `_java_entity` returning the underlying Neo4j Node or Relationship.
6
6
  module Index
7
7
 
8
8
  # Adds an index on the given property
@@ -16,7 +16,7 @@ module Neo4j
16
16
  # @see Neo4j::Core::Index::ClassMethods#add_index
17
17
  #
18
18
  def add_index(field, value=self[field])
19
- self.class.add_index(java_entity, field.to_s, value)
19
+ self.class.add_index(_java_entity, field.to_s, value)
20
20
  end
21
21
 
22
22
  # Removes an index on the given property.
@@ -26,7 +26,7 @@ module Neo4j
26
26
  # @see Neo4j::Core::Index::ClassMethods#rm_index
27
27
  #
28
28
  def rm_index(field, value=self[field])
29
- self.class.rm_index(java_entity, field.to_s, value)
29
+ self.class.rm_index(_java_entity, field.to_s, value)
30
30
  end
31
31
 
32
32
  end
@@ -112,6 +112,9 @@ module Neo4j
112
112
  # @example Sorting using the builder pattern
113
113
  # Person.find(:name => 'kalle').asc(:name)
114
114
  #
115
+ # @example Searching by a set of values, OR search
116
+ # Person.find(:name => ['kalle', 'sune', 'jimmy'])
117
+ #
115
118
  # @example Compound queries and Range queries
116
119
  # Person.find('name: pelle').and(:age).between(2, 5)
117
120
  # Person.find(:name => 'kalle', :age => (2..5))
@@ -143,6 +146,23 @@ module Neo4j
143
146
  end
144
147
  end
145
148
 
149
+ # Add the entity to this index for the given key/value pair if this particular key/value pair doesn't already exist.
150
+ # This ensures that only one entity will be associated with the key/value pair even if multiple transactions are trying to add it at the same time.
151
+ # One of those transactions will win and add it while the others will block, waiting for the winning transaction to finish.
152
+ # If the winning transaction was successful these other transactions will return the associated entity instead of adding it.
153
+ # If it wasn't successful the waiting transactions will begin a new race to add it.
154
+ #
155
+ # @param [Neo4j::Node, Neo4j::Relationship] entity the entity (i.e Node or Relationship) to associate the key/value pair with.
156
+ # @param [String, Symbol] key the key in the key/value pair to associate with the entity.
157
+ # @param [String, Fixnum, Float] value the value in the key/value pair to associate with the entity.
158
+ # @param [Symbol] index_type the type of lucene index
159
+ # @return [nil, Neo4j:Node, Neo4j::Relationship] the previously indexed entity, or nil if no entity was indexed before (and the specified entity was added to the index).
160
+ # @see Neo4j::Core::Index::UniqueFactory as an alternative which probably simplify creating unique entities
161
+ def put_if_absent(entity, key, value, index_type = :exact)
162
+ index = index_for_type(index_type)
163
+ index.put_if_absent(entity, key.to_s, value)
164
+ end
165
+
146
166
  # Delete all index configuration. No more automatic indexing will be performed
147
167
  def rm_index_config
148
168
  @config.rm_index_config
@@ -224,13 +224,25 @@ module Neo4j
224
224
  if type != String
225
225
  if Range === value
226
226
  and_query.add(range_query(key, value.first, value.last, true, !value.exclude_end?), Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
227
+ elsif Array === value
228
+ value.each do |v|
229
+ and_query.add(range_query(key, v, v, true, true), Java::OrgApacheLuceneSearch::BooleanClause::Occur::SHOULD)
230
+ end
227
231
  else
228
232
  and_query.add(range_query(key, value, value, true, true), Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
229
233
  end
230
234
  else
231
- term = Java::OrgApacheLuceneIndex::Term.new(key.to_s, value.to_s)
232
- term_query = Java::OrgApacheLuceneSearch::TermQuery.new(term)
233
- and_query.add(term_query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
235
+ if Array === value
236
+ value.each do |v|
237
+ term = Java::OrgApacheLuceneIndex::Term.new(key.to_s, v.to_s)
238
+ term_query = Java::OrgApacheLuceneSearch::TermQuery.new(term)
239
+ and_query.add(term_query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::SHOULD)
240
+ end
241
+ else
242
+ term = Java::OrgApacheLuceneIndex::Term.new(key.to_s, value.to_s)
243
+ term_query = Java::OrgApacheLuceneSearch::TermQuery.new(term)
244
+ and_query.add(term_query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
245
+ end
234
246
  end
235
247
  end
236
248
  and_query
@@ -0,0 +1,54 @@
1
+ module Neo4j
2
+ module Core
3
+
4
+ module Index
5
+
6
+ # A Utility class that can be used to make it easier to create unique entities. It uses {Neo4j::Core::Index::Indexer#put_if_absent}.
7
+ #
8
+ # @see Indexer#put_if_absent
9
+ #
10
+ # @example
11
+ # index = index_for_type(:exact)
12
+ # Neo4j::Core::Index::UniqueFactory.new(:email, index) { |k,v| Neo4j::Node.new(k => v) }.get_or_create(:email, 'foo@gmail.com')
13
+ #
14
+ class UniqueFactory
15
+ # @param [Symbol] key only one key is possible
16
+ # @param [Java::Neo4j] index the lucene index (see #index_for_type)
17
+ # @yield a proc for initialize each created entity
18
+ def initialize(key, index, &entity_creator_block)
19
+ @key = key
20
+ @index = index
21
+ @entity_creator_block = entity_creator_block || Proc.new{|k,v| Neo4j::Node.new(key.to_s => v)}
22
+ end
23
+
24
+ # Get the indexed entity, creating it (exactly once) if no indexed entity exists.
25
+ # There must be an index on the key
26
+ # @param [Symbol] key the key to find the entity under in the index.
27
+ # @param [String, Fixnum, Float] value the value the key is mapped to for the entity in the index.
28
+ # @param [Hash] props optional properties that the entity will have if created
29
+ # @yield optional, make it possible to initialize the created node in a block
30
+ def get_or_create(key, value, props=nil, &init_block)
31
+ tx = Neo4j::Transaction.new
32
+ result = @index.get(key.to_s, value).get_single
33
+ return result if result
34
+
35
+ created = @entity_creator_block.call(key,value)
36
+ result = @index.put_if_absent(created._java_entity, key.to_s, value)
37
+ if result.nil?
38
+ props.each_pair{|k,v| created[k.to_s] = v} if props
39
+ init_block.call(result) if init_block
40
+ result = created
41
+ else
42
+ created.del
43
+ end
44
+ tx.success
45
+ result
46
+ ensure
47
+ tx.finish
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -60,7 +60,7 @@ module Neo4j
60
60
 
61
61
  # same as #_java_rel
62
62
  # Used so that we have same method for both relationship and nodes
63
- def java_entity
63
+ def _java_entity
64
64
  self
65
65
  end
66
66
 
@@ -2,6 +2,8 @@ module Neo4j
2
2
  module Core
3
3
  # Contains methods for traversing relationship object of depth one from one node.
4
4
  module Rels
5
+
6
+
5
7
  # Returns the only node of a given type and direction that is attached to this node, or nil.
6
8
  # This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or one relationships of a given type and direction to another node.
7
9
  # Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships exist, it is a fatal error that should generate an exception.
@@ -124,6 +126,7 @@ module Neo4j
124
126
  end
125
127
  end
126
128
 
129
+
127
130
  # Check if the given relationship exists
128
131
  # Returns true if there are one or more relationships from this node to other nodes
129
132
  # with the given relationship.
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Core
3
- VERSION = "0.0.13"
3
+ VERSION = "0.0.14"
4
4
  end
5
5
  end
@@ -12,7 +12,7 @@ module Neo4j
12
12
  # This can be implemented by a wrapper to returned the underlying java node or relationship.
13
13
  # You can override this method in your own wrapper class.
14
14
  # @return self
15
- def java_entity
15
+ def _java_entity
16
16
  self
17
17
  end
18
18
  end
data/lib/neo4j-core.rb CHANGED
@@ -37,6 +37,7 @@ require 'neo4j-core/index/indexer_registry'
37
37
  require 'neo4j-core/index/index_config'
38
38
  require 'neo4j-core/index/indexer'
39
39
  require 'neo4j-core/index/lucene_query'
40
+ require 'neo4j-core/index/unique_factory'
40
41
 
41
42
  require 'neo4j-core/equal/equal'
42
43
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: neo4j-core
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.13
5
+ version: 0.0.14
6
6
  platform: java
7
7
  authors:
8
8
  - Andreas Ronge
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-23 00:00:00 Z
13
+ date: 2012-04-24 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: neo4j-community
@@ -72,6 +72,7 @@ files:
72
72
  - lib/neo4j-core/index/indexer.rb
73
73
  - lib/neo4j-core/index/lucene_query.rb
74
74
  - lib/neo4j-core/index/indexer_registry.rb
75
+ - lib/neo4j-core/index/unique_factory.rb
75
76
  - lib/neo4j-core/index/class_methods.rb
76
77
  - lib/neo4j-core/index/index.rb
77
78
  - lib/neo4j-core/relationship/class_methods.rb