neo4j-wrapper 0.0.9-java → 0.0.10-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -115,12 +115,12 @@ module Neo4j
115
115
 
116
116
  def to_java(value)
117
117
  return nil if value.nil?
118
- value.to_s
118
+ Array === value ? value.map(&:to_s) : value.to_s
119
119
  end
120
120
 
121
121
  def to_ruby(value)
122
122
  return nil if value.nil?
123
- value.to_s
123
+ value
124
124
  end
125
125
 
126
126
  def index_as
@@ -141,12 +141,12 @@ module Neo4j
141
141
 
142
142
  def to_java(value)
143
143
  return nil if value.nil?
144
- value.to_i
144
+ Array === value ? value.map(&:to_i) : value.to_i
145
145
  end
146
146
 
147
147
  def to_ruby(value)
148
148
  return nil if value.nil?
149
- value.to_i
149
+ value#.to_i
150
150
  end
151
151
 
152
152
  def index_as
@@ -165,12 +165,12 @@ module Neo4j
165
165
 
166
166
  def to_java(value)
167
167
  return nil if value.nil?
168
- value.to_f
168
+ Array === value ? value.map(&:to_f) : value.to_f
169
169
  end
170
170
 
171
171
  def to_ruby(value)
172
172
  return nil if value.nil?
173
- value.to_f
173
+ value
174
174
  end
175
175
 
176
176
  def index_as
@@ -41,6 +41,7 @@ module Neo4j
41
41
  # class FolderNode
42
42
  # include Ne4j::NodeMixin
43
43
  # has_n(:files).to(File)
44
+ # # Same as has_n(:files).to("File")
44
45
  # end
45
46
  #
46
47
  # FolderNode.files #=> 'File#files' the name of the relationship
@@ -50,6 +51,8 @@ module Neo4j
50
51
  # # generate accessor method for traversing and adding relationship on incoming nodes.
51
52
  # class FileNode
52
53
  # include Ne4j::NodeMixin
54
+ # has_one(:folder).from(FolderNode.files)
55
+ # # or same as
53
56
  # has_one(:folder).from(FolderNode, :files)
54
57
  # end
55
58
  #
@@ -79,7 +82,7 @@ module Neo4j
79
82
 
80
83
  instance_eval(%Q{
81
84
  def #{rel_type}
82
- _decl_rels[:#{rel_type}].rel_type.to_s
85
+ _decl_rels[:#{rel_type}].rel_type
83
86
  end}, __FILE__, __LINE__)
84
87
 
85
88
  _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, false, clazz)
@@ -125,7 +128,7 @@ module Neo4j
125
128
 
126
129
  instance_eval(%Q{
127
130
  def #{rel_type}
128
- _decl_rels[:#{rel_type}].rel_type.to_s
131
+ _decl_rels[:#{rel_type}].rel_type
129
132
  end}, __FILE__, __LINE__)
130
133
 
131
134
  _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, true, clazz)
@@ -33,30 +33,30 @@ module Neo4j
33
33
  # <b>File#folder</b> :: for accessing nodes from relationship 'files' from the outgoing Folder node
34
34
  #
35
35
  class DeclRel
36
- attr_reader :target_class, :source_class, :dir, :rel_type
36
+ attr_reader :source_class, :dir, :rel_type
37
37
 
38
- def initialize(method_id, has_one, target_class)
38
+ def initialize(method_id, has_one, source_class)
39
39
  @method_id = method_id
40
40
  @has_one = has_one
41
- @target_class = target_class
42
41
  @dir = :outgoing
43
- @rel_type = method_id.to_s
44
- @source_class = target_class
42
+ @rel_type = method_id.to_sym
43
+ @source_class = source_class
45
44
  end
46
45
 
47
46
  def inherit_new
48
47
  base = self
49
- dr = DeclRel.new(@method_id, @has_one, @target_class)
48
+ dr = DeclRel.new(@method_id, @has_one, @source_class)
50
49
  dr.instance_eval do
51
50
  @dir = base.dir
52
51
  @rel_type = base.rel_type
52
+ @target_name = base.target_name if base.target_name
53
53
  @source_class = base.source_class
54
54
  end
55
55
  dr
56
56
  end
57
57
 
58
58
  def to_s
59
- "DeclRel #{object_id} dir: #{@dir} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
59
+ "DeclRel #{object_id} dir: #{@dir} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_name} rel_class:#{@relationship}"
60
60
  end
61
61
 
62
62
  # @return [true, false]
@@ -75,13 +75,15 @@ module Neo4j
75
75
  end
76
76
 
77
77
 
78
- # Specifies an outgoing relationship.
79
- # The name of the outgoing class will be used as a prefix for the relationship used.
78
+ # Declares an outgoing relationship type.
79
+ # It is possible to prefix relationship types so that it's possible to distinguish different incoming relationships.
80
+ # There is no validation that the added node is of the specified class.
80
81
  #
81
82
  # @example Example
82
83
  # class FolderNode
83
84
  # include Neo4j::NodeMixin
84
85
  # has_n(:files).to(FileNode)
86
+ # has_one(:root).to("FileSystem") # also possible, if the class is not defined yet
85
87
  # end
86
88
  #
87
89
  # folder = FolderNode.new
@@ -99,18 +101,20 @@ module Neo4j
99
101
  # # create an outgoing relationship of type 'contains' from folder node to file
100
102
  # folder.files << FolderNode.new
101
103
  #
102
- # @param [Class] target the other class to which this relationship goes
104
+ # @param [Class, String, Symbol] target the other class to which this relationship goes (if String or Class) or the relationship (if Symbol)
105
+ # @param [Class, String, Symbol] rel_type the rel_type postfix for the relationships, which defaults to the same as the has_n/one method id
103
106
  # @return self
104
- def to(target)
107
+ def to(target, rel_type = @method_id)
105
108
  @dir = :outgoing
106
109
 
107
- if Class === target
110
+ if Class === target || String === target
108
111
  # handle e.g. has_n(:friends).to(class)
109
- @target_class = target
110
- @rel_type = "#{@source_class}##{@method_id}"
112
+ @target_name = target
113
+ @rel_type = "#{@source_class}##{rel_type}".to_sym
111
114
  elsif Symbol === target
112
- # handle e.g. has_n(:friends).to(:knows)
113
- @rel_type = target.to_s
115
+ # handle e.g. has_n(:friends).to(:knows) or to("Person#friends")
116
+ @target_name = target.to_s.split("#")[0] if target.to_s.include?("#")
117
+ @rel_type = target.to_sym
114
118
  else
115
119
  raise "Expected a class or a symbol for, got #{target}/#{target.class}"
116
120
  end
@@ -129,7 +133,8 @@ module Neo4j
129
133
  # class FileNode
130
134
  # include Neo4j::NodeMixin
131
135
  # # will only traverse any incoming relationship of type files from node FileNode
132
- # has_one(:folder).from(FolderNode, :files)
136
+ # has_one(:folder).from(FolderNode.files)
137
+ # # alternative: has_one(:folder).from(FolderNode, :files)
133
138
  # end
134
139
  #
135
140
  # file = FileNode.new
@@ -158,14 +163,18 @@ module Neo4j
158
163
 
159
164
  if args.size > 1
160
165
  # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
161
- @target_class = args[0]
162
- @rel_type = "#{@target_class}##{args[1]}"
166
+ @target_name = args[0]
163
167
  @relationship_name = args[1].to_sym
168
+ @rel_type = "#{@target_name}##{args[1]}".to_sym
164
169
  elsif Symbol === args[0]
165
170
  # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
166
- @rel_type = args[0].to_s
171
+ name = args[0].to_s
172
+ if name.include?("#")
173
+ @target_name, @relationship_name = name.split("#").map(&:to_sym)
174
+ end
175
+ @rel_type = args[0]
167
176
  else
168
- raise "Expected a symbol for, got #{args[0]}"
177
+ raise "Expected a symbol for, got #{args[0].inspect}"
169
178
  end
170
179
  self
171
180
  end
@@ -195,20 +204,29 @@ module Neo4j
195
204
  self
196
205
  end
197
206
 
207
+ # @private
208
+ def target_name
209
+ @target_name
210
+ end
198
211
 
199
212
  # @private
200
213
  def relationship_class # :nodoc:
201
- if !@relationship_name.nil? && @relationship.nil?
202
- other_class_dsl = @target_class._decl_rels[@relationship_name]
214
+ if @dir == :incoming
215
+ other_class_dsl = target_class && target_class._decl_rels[@relationship_name]
203
216
  if other_class_dsl
204
217
  @relationship = other_class_dsl.relationship_class
205
218
  else
206
- Neo4j.logger.warn "Unknown outgoing relationship #{@relationship_name} on #{@target_class}"
219
+ Neo4j.logger.warn "Unknown outgoing relationship #{@relationship_name} on #{@target_name}"
207
220
  end
208
221
  end
209
222
  @relationship
210
223
  end
211
224
 
225
+ def target_class
226
+ @target_name && (@target_name.is_a?(Class) ? @target_name : Neo4j::Wrapper.to_class(@target_name.to_s))
227
+ end
228
+
229
+
212
230
  # @private
213
231
  def each_node(node, &block)
214
232
  node.rels(dir, rel_type).each do |rel|
@@ -48,6 +48,38 @@ module Neo4j
48
48
 
49
49
  alias_method :create, :new
50
50
 
51
+
52
+ # Get the indexed entity, creating it (exactly once) if no indexed entity exist.
53
+ #
54
+ # @example Creating a Unique node
55
+ #
56
+ # class MyNode
57
+ # include Neo4j::NodeMixin
58
+ # property :email, :index => :exact, :unique => true
59
+ # end
60
+ #
61
+ # node = MyNode.get_or_create(:email =>'jimmy@gmail.com', :name => 'jimmy')
62
+ #
63
+ # @see #put_if_absent
64
+ def get_or_create(*args)
65
+ props = args.first
66
+ raise "Can't get or create entity since #{props.inspect} does not included unique key #{props[unique_factory_key]}'" unless props[unique_factory_key]
67
+ index = index_for_type(_decl_props[unique_factory_key][:index])
68
+ Neo4j::Core::Index::UniqueFactory.new(unique_factory_key, index) { |*| new(*args) }.get_or_create(unique_factory_key, props[unique_factory_key])
69
+ end
70
+
71
+ # @throws Exception if there are more then one property having unique index
72
+ # @return [Symbol,nil] the property which has an unique index or nil
73
+ def unique_factory_key
74
+ @unique_factory_key ||= begin
75
+ unique = []
76
+ _decl_props.each_pair { |k, v| unique << k if v[:unique] }
77
+ return nil if unique.empty?
78
+ raise "Only one property can be unique, got #{unique.join(', ')}" if unique.size > 1
79
+ unique.first
80
+ end
81
+ end
82
+
51
83
  # Loads a wrapped node from the database given a neo id.
52
84
  # @param [#to_i, nil] neo_id
53
85
  # @return [Object, nil] If the node does not exist it will return nil otherwise the loaded node or wrapped node.
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Wrapper
3
- VERSION = '0.0.9'
3
+ VERSION = '0.0.10'
4
4
  end
5
5
  end
@@ -27,5 +27,5 @@ It comes included with the Apache Lucene document database.
27
27
  s.extra_rdoc_files = %w( README.rdoc )
28
28
  s.rdoc_options = ["--quiet", "--title", "Neo4j.rb", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
29
29
 
30
- s.add_dependency("neo4j-core", "0.0.13")
30
+ s.add_dependency("neo4j-core", "0.0.14")
31
31
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: neo4j-wrapper
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.9
5
+ version: 0.0.10
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-core
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - "="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.0.13
23
+ version: 0.0.14
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
26
  description: |