neo4j-core 3.0.0 → 3.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9b416de0287b913be5f84220b4c2d5fb6b8012a
4
- data.tar.gz: 4751578b98692e10782620037c596cf983a8353b
3
+ metadata.gz: 66251bf61bb42f0f8f74378b2c6da243cc730172
4
+ data.tar.gz: 78bd05d535dea67264c20e5e72f3f46f7af7b84a
5
5
  SHA512:
6
- metadata.gz: a7a595759c87818f75f869dcc6ce04250834236c5c13dce315f2aa1d7eace080b74443f6aa581d0732c089fcc7a5080858eeee0a6e4116bd077ccb6c3a05df06
7
- data.tar.gz: 6764c3d207e04008f45e7912508f31464fc263772f3fc606bd955beb9ce160e8d54bb35a5f08d95645f5f8a8977a89597d75c66ef2eb0df89a7f50ff70763eee
6
+ metadata.gz: b4309cc95b32c1d44afb6bc92c558378d0d2acef61ee85312eb24678bb585167622e3f56ee1d0b1f77412d9aa42bd0bdca29df45d827871a6e1ce5d055cd09e4
7
+ data.tar.gz: 3b94371cd1cf479225030e5e359eb3d97dd4c834e13496e6626b12828e95063ffe7ea08e197a69fe3324adf507d6f71bc26b5ecb2b3bccd00ec99ab8c8e5794a
@@ -134,7 +134,11 @@ module Neo4j::Core
134
134
 
135
135
  def attributes_string(attributes)
136
136
  attributes_string = attributes.map do |key, value|
137
- v = value.to_s.match(/^{.+}$/) ? value : value.inspect
137
+ v = if value.nil?
138
+ 'null'
139
+ else
140
+ value.to_s.match(/^{.+}$/) ? value : value.inspect
141
+ end
138
142
  "#{key}: #{v}"
139
143
  end.join(', ')
140
144
 
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Core
3
- VERSION = "3.0.0"
3
+ VERSION = "3.0.1"
4
4
  end
5
5
  end
@@ -113,6 +113,10 @@ module Neo4j::Embedded
113
113
  nil
114
114
  end
115
115
  tx_methods :del
116
+ tx_methods :delete
117
+
118
+ alias_method :destroy, :del
119
+ tx_methods :destroy
116
120
 
117
121
  def create_rel(type, other_node, props = nil)
118
122
  rel = create_relationship_to(other_node.neo4j_obj, ToJava.type_to_java(type))
@@ -47,6 +47,10 @@ module Neo4j::Embedded
47
47
  delete
48
48
  end
49
49
  tx_methods :del
50
+ tx_methods :delete
51
+
52
+ alias_method :destroy, :del
53
+ tx_methods :destroy
50
54
 
51
55
  def other_node(n)
52
56
  _other_node(n.neo4j_obj).wrapper
@@ -33,7 +33,8 @@ module Neo4j::Server
33
33
  def create_rel(type, other_node, props = nil)
34
34
  q = "START a=node(#{neo_id}), b=node(#{other_node.neo_id}) CREATE (a)-[r:`#{type}` #{cypher_prop_list(props)}]->(b) RETURN ID(r)"
35
35
  id = @session._query_or_fail(q, true)
36
- CypherRelationship.new(@session, id, type)
36
+ data_hash = { 'type' => type, 'data' => props, 'start' => self.neo_id.to_s, 'end' => other_node.neo_id.to_s, 'id' => id }
37
+ CypherRelationship.new(@session, data_hash)
37
38
  end
38
39
 
39
40
  # (see Neo4j::Node#props)
@@ -142,6 +143,9 @@ module Neo4j::Server
142
143
  @session._query_or_fail("START n = node(#{neo_id}) MATCH n-[r]-() DELETE r")
143
144
  @session._query_or_fail("START n = node(#{neo_id}) DELETE n")
144
145
  end
146
+ alias_method :delete, :del
147
+ alias_method :destroy, :del
148
+
145
149
 
146
150
  # (see Neo4j::Node#exist?)
147
151
  def exist?
@@ -158,33 +162,33 @@ module Neo4j::Server
158
162
 
159
163
  # (see Neo4j::Node#node)
160
164
  def node(match={})
161
- result = match(CypherNode, "ID(p)", match)
165
+ result = match(CypherNode, "p as result LIMIT 2", match)
162
166
  raise "Expected to only find one relationship from node #{neo_id} matching #{match.inspect} but found #{result.count}" if result.count > 1
163
167
  result.first
164
168
  end
165
169
 
166
170
  # (see Neo4j::Node#rel)
167
171
  def rel(match={})
168
- result = match(CypherRelationship, "ID(r), TYPE(r)", match)
172
+ result = match(CypherRelationship, "r as result LIMIT 2", match)
169
173
  raise "Expected to only find one relationship from node #{neo_id} matching #{match.inspect} but found #{result.count}" if result.count > 1
170
174
  result.first
171
175
  end
172
176
 
173
177
  # (see Neo4j::Node#rel?)
174
178
  def rel?(match={})
175
- result = match(CypherRelationship, "ID(r), TYPE(r)", match)
179
+ result = match(CypherRelationship, "r as result", match)
176
180
  !!result.first
177
181
  end
178
182
 
179
183
  # (see Neo4j::Node#nodes)
180
184
  def nodes(match={})
181
- match(CypherNode, "ID(p)", match)
185
+ match(CypherNode, "p as result", match)
182
186
  end
183
187
 
184
188
 
185
189
  # (see Neo4j::Node#rels)
186
190
  def rels(match = {dir: :both})
187
- match(CypherRelationship, "ID(r), TYPE(r)", match)
191
+ match(CypherRelationship, "r as result", match)
188
192
  end
189
193
 
190
194
  # @private
@@ -199,17 +203,11 @@ module Neo4j::Server
199
203
  cypher = "START n=node(#{neo_id}) #{between_id} MATCH (n)#{dir_func.call(cypher_rel)}(p) RETURN #{returns}"
200
204
  r = @session._query(cypher)
201
205
  r.raise_error if r.error?
202
- _map_result(r, clazz)
206
+ _map_result(r)
203
207
  end
204
208
 
205
- # @private
206
- def _map_result(r, clazz)
207
- r.data.map do |rel|
208
- next if r.uncommited? ? rel['row'].first.nil? : rel.first.nil?
209
- row = r.uncommited? ? rel['row'] : rel
210
- clazz.new(@session, *row).wrapper
211
- end.compact
209
+ def _map_result(r)
210
+ r.to_node_enumeration.map { |rel| rel.result }
212
211
  end
213
-
214
212
  end
215
213
  end
@@ -5,23 +5,14 @@ module Neo4j::Server
5
5
  include Neo4j::Core::CypherTranslator
6
6
  include Neo4j::Core::ActiveEntity
7
7
 
8
- attr_reader :start_node_neo_id, :end_node_neo_id
9
-
10
- def initialize(session, value, rel_type = nil)
8
+ def initialize(session, value)
11
9
  @session = session
12
-
13
- @id = if value.is_a?(Hash)
14
- @response_hash = value
15
- @rel_type = @response_hash['type']
16
- @props = @response_hash['data']
17
- @start_node_neo_id = @response_hash['start'].match(/\d+$/)[0].to_i
18
- @end_node_neo_id = @response_hash['end'].match(/\d+$/)[0].to_i
19
- @response_hash['id']
20
- else
21
- @rel_type = rel_type
22
-
23
- value
24
- end
10
+ @response_hash = value
11
+ @rel_type = @response_hash['type']
12
+ @props = @response_hash['data']
13
+ @start_node_neo_id = @response_hash['start'].match(/\d+$/)[0].to_i
14
+ @end_node_neo_id = @response_hash['end'].match(/\d+$/)[0].to_i
15
+ @id = @response_hash['id']
25
16
  end
26
17
 
27
18
  def ==(o)
@@ -29,21 +20,32 @@ module Neo4j::Server
29
20
  end
30
21
  alias_method :eql?, :==
31
22
 
32
- def neo_id
23
+ def id
33
24
  @id
34
25
  end
35
26
 
27
+ def neo_id
28
+ id
29
+ end
30
+
36
31
  def inspect
37
32
  "CypherRelationship #{neo_id}"
38
33
  end
39
34
 
40
35
  def load_resource
41
- id = neo_id
42
- unless @resource_data
36
+ if resource_data.nil? || resource_data.empty?
43
37
  @resource_data = @session._query_or_fail("START n=relationship(#{id}) RETURN n", true) # r.first_data
44
38
  end
45
39
  end
46
40
 
41
+ def start_node_neo_id
42
+ @start_node_neo_id
43
+ end
44
+
45
+ def end_node_neo_id
46
+ @end_node_neo_id
47
+ end
48
+
47
49
  def _start_node_id
48
50
  @start_node_neo_id ||= get_node_id(:start)
49
51
  end
@@ -53,15 +55,12 @@ module Neo4j::Server
53
55
  end
54
56
 
55
57
  def _start_node
56
- load_resource
57
- id = resource_url_id(resource_url(:start))
58
- Neo4j::Node._load(id)
58
+ @_start_node ||= Neo4j::Node._load(start_node_neo_id)
59
59
  end
60
60
 
61
61
  def _end_node
62
62
  load_resource
63
- id = resource_url_id(resource_url(:end))
64
- Neo4j::Node._load(id)
63
+ @_end_node ||= Neo4j::Node._load(end_node_neo_id)
65
64
  end
66
65
 
67
66
  def get_node_id(direction)
@@ -70,17 +69,14 @@ module Neo4j::Server
70
69
  end
71
70
 
72
71
  def get_property(key)
73
- id = neo_id
74
72
  @session._query_or_fail("START n=relationship(#{id}) RETURN n.`#{key}`", true)
75
73
  end
76
74
 
77
75
  def set_property(key,value)
78
- id = neo_id
79
76
  @session._query_or_fail("START n=relationship(#{id}) SET n.`#{key}` = {value}", false, {value: value})
80
77
  end
81
78
 
82
79
  def remove_property(key)
83
- id = neo_id
84
80
  @session._query_or_fail("START n=relationship(#{id}) REMOVE n.`#{key}`")
85
81
  end
86
82
 
@@ -118,6 +114,8 @@ module Neo4j::Server
118
114
  id = neo_id
119
115
  @session._query("START n=relationship(#{id}) DELETE n").raise_unless_response_code(200)
120
116
  end
117
+ alias_method :delete, :del
118
+ alias_method :destroy, :del
121
119
 
122
120
  def exist?
123
121
  id = neo_id
@@ -50,25 +50,21 @@ module Neo4j::Server
50
50
 
51
51
  def to_node_enumeration(cypher = '', session = Neo4j::Session.current)
52
52
  Enumerator.new do |yielder|
53
+ @result_index = 0
53
54
  self.to_struct_enumeration(cypher).each do |row|
55
+ @row_index = 0
54
56
  yielder << row.each_pair.each_with_object(@struct.new) do |(column, value), result|
55
57
  result[column] = map_row_value(value, session)
58
+ @row_index += 1
56
59
  end
60
+ @result_index += 1
57
61
  end
58
62
  end
59
63
  end
60
64
 
61
65
  def map_row_value(value, session)
62
66
  if value.is_a?(Hash)
63
- if value['labels']
64
- add_entity_id(value)
65
- CypherNode.new(session, value).wrapper
66
- elsif value['type']
67
- add_entity_id(value)
68
- CypherRelationship.new(session, value).wrapper
69
- else
70
- value
71
- end
67
+ hash_value_as_object(value, session)
72
68
  elsif value.is_a?(Array)
73
69
  value.map {|v| map_row_value(v, session) }
74
70
  else
@@ -76,6 +72,18 @@ module Neo4j::Server
76
72
  end
77
73
  end
78
74
 
75
+ def hash_value_as_object(value, session)
76
+ return value unless value['labels'] || value['type'] || is_transaction_response?
77
+ obj_type, data = if value['labels'] || value['type']
78
+ add_entity_id(value)
79
+ [(value['labels'] ? CypherNode : CypherRelationship), value]
80
+ else
81
+ add_transaction_entity_id
82
+ [(mapped_rest_data['start'] ? CypherRelationship : CypherNode), mapped_rest_data]
83
+ end
84
+ obj_type.new(session, data).wrapper
85
+ end
86
+
79
87
  attr_reader :struct
80
88
 
81
89
  def initialize(response, uncommited = false)
@@ -83,7 +91,6 @@ module Neo4j::Server
83
91
  @uncommited = uncommited
84
92
  end
85
93
 
86
-
87
94
  def entity_data(id=nil)
88
95
  if uncommited?
89
96
  data = @data.first['row'].first
@@ -108,6 +115,10 @@ module Neo4j::Server
108
115
  data.merge!({'id' => data['self'].split('/')[-1].to_i})
109
116
  end
110
117
 
118
+ def add_transaction_entity_id
119
+ mapped_rest_data.merge!({'id' => mapped_rest_data['self'].split('/').last.to_i})
120
+ end
121
+
111
122
  def error?
112
123
  !!@error
113
124
  end
@@ -116,6 +127,10 @@ module Neo4j::Server
116
127
  @uncommited
117
128
  end
118
129
 
130
+ def has_data?
131
+ !response.body['data'].nil?
132
+ end
133
+
119
134
  def raise_unless_response_code(code)
120
135
  raise "Response code #{response.code}, expected #{code} for #{response.request.path}, #{response.body}" unless response.status == code
121
136
  end
@@ -179,5 +194,32 @@ module Neo4j::Server
179
194
  end
180
195
  cr
181
196
  end
197
+
198
+ def is_transaction_response?
199
+ !self.response.body['results'].nil?
200
+ end
201
+
202
+ def rest_data
203
+ @result_index = @row_index = 0
204
+ mapped_rest_data
205
+ end
206
+
207
+ def rest_data_with_id
208
+ rest_data.merge!({'id' => mapped_rest_data['self'].split('/').last.to_i})
209
+ end
210
+
211
+ private
212
+
213
+ def row_index
214
+ @row_index
215
+ end
216
+
217
+ def result_index
218
+ @result_index
219
+ end
220
+
221
+ def mapped_rest_data
222
+ self.response.body['results'][0]['data'][result_index]['rest'][row_index]
223
+ end
182
224
  end
183
- end
225
+ end
@@ -104,24 +104,28 @@ module Neo4j::Server
104
104
 
105
105
  def load_node(neo_id)
106
106
  cypher_response = _query("START n=node(#{neo_id}) RETURN n")
107
- if (!cypher_response.error?)
108
- result = cypher_response.entity_data(neo_id)
109
- CypherNode.new(self, result)
110
- elsif (cypher_response.error_status =~ /EntityNotFound/)
111
- return nil
112
- else
113
- cypher_response.raise_error
114
- end
107
+ load_entity(CypherNode, cypher_response)
115
108
  end
116
109
 
117
110
  def load_relationship(neo_id)
118
- cypher_response = _query("START r=relationship(#{neo_id}) RETURN TYPE(r)")
119
- if (!cypher_response.error?)
120
- CypherRelationship.new(self, neo_id, cypher_response.first_data)
121
- elsif (cypher_response.error_msg =~ /not found/) # Ugly that the Neo4j API gives us this error message
111
+ cypher_response = _query("START r=relationship(#{neo_id}) RETURN r")
112
+ load_entity(CypherRelationship, cypher_response)
113
+ end
114
+
115
+ def load_entity(clazz, cypher_response)
116
+ return nil if cypher_response.data.nil? || cypher_response.data[0].nil?
117
+ data = if cypher_response.is_transaction_response?
118
+ cypher_response.rest_data_with_id
119
+ else
120
+ cypher_response.first_data
121
+ end
122
+
123
+ if cypher_response.error?
124
+ cypher_response.raise_error
125
+ elsif cypher_response.error_msg =~ /not found/ # Ugly that the Neo4j API gives us this error message
122
126
  return nil
123
127
  else
124
- cypher_response.raise_error
128
+ clazz.new(self, data)
125
129
  end
126
130
  end
127
131
 
@@ -254,27 +258,27 @@ module Neo4j::Server
254
258
  end
255
259
 
256
260
 
257
- def search_result_to_enumerable(response, ret, map)
258
- return [] unless response.data
259
-
260
- if (ret.size == 1)
261
- Enumerator.new do |yielder|
262
- response.data.each do |data|
263
- yielder << map_column(key, map, data[0])
264
- end
265
- end
266
-
267
- else
268
- Enumerator.new do |yielder|
269
- response.data.each do |data|
270
- hash = {}
271
- ret.each_with_index do |key, i|
272
- hash[key] = map_column(key, map, data[i])
273
- end
274
- yielder << hash
275
- end
276
- end
277
- end
278
- end
261
+ # def search_result_to_enumerable(response, ret, map)
262
+ # return [] unless response.data
263
+
264
+ # if (ret.size == 1)
265
+ # Enumerator.new do |yielder|
266
+ # response.data.each do |data|
267
+ # yielder << map_column(key, map, data[0])
268
+ # end
269
+ # end
270
+
271
+ # else
272
+ # Enumerator.new do |yielder|
273
+ # response.data.each do |data|
274
+ # hash = {}
275
+ # ret.each_with_index do |key, i|
276
+ # hash[key] = map_column(key, map, data[i])
277
+ # end
278
+ # yielder << hash
279
+ # end
280
+ # end
281
+ # end
282
+ # end
279
283
  end
280
284
  end
@@ -26,41 +26,25 @@ module Neo4j::Server
26
26
  end
27
27
 
28
28
  def _query(cypher_query, params=nil)
29
- statement = {statement: cypher_query}
30
- body = {statements: [statement]}
31
-
32
- if params
33
- # TODO can't get this working for some reason using parameters
34
- #props = params.keys.inject({}) do|ack, k|
35
- # ack[k] = {name: params[k]}
36
- # ack
37
- #end
38
- #statement[:parameters] = props
39
-
40
- # So we have to do this workaround
41
- params.each_pair do |k,v|
42
- statement[:statement].gsub!("{ #{k} }", "#{escape_value(v)}")
43
- end
44
- end
29
+ statement = { statement: cypher_query, parameters: params, resultDataContents: ['row', 'REST'] }
30
+ body = { statements: [statement] }
45
31
  response = @connection.post(@exec_url, body)
46
32
  _create_cypher_response(response)
47
33
  end
48
34
 
49
35
  def _create_cypher_response(response)
50
36
  first_result = response.body['results'][0]
51
- cr = CypherResponse.new(response, true)
52
37
 
53
- if (response.body['errors'].empty?)
54
- cr.set_data(first_result['data'], first_result['columns'])
55
- else
38
+ cr = CypherResponse.new(response, true)
39
+ if !response.body['errors'].empty?
56
40
  first_error = response.body['errors'].first
57
41
  cr.set_error(first_error['message'], first_error['code'], first_error['code'])
42
+ else
43
+ cr.set_data(first_result['data'], first_result['columns'])
58
44
  end
59
45
  cr
60
46
  end
61
47
 
62
-
63
-
64
48
  def _delete_tx
65
49
  response = @connection.delete(@exec_url, headers: resource_headers)
66
50
  expect_response_code(response,200)
@@ -74,4 +58,4 @@ module Neo4j::Server
74
58
  response
75
59
  end
76
60
  end
77
- end
61
+ end
@@ -16,8 +16,9 @@ module Neo4j
16
16
  end
17
17
 
18
18
 
19
- def wrap_resource(db, rel, resource_class, verb=:get, payload={}, connection)
19
+ def wrap_resource(db, rel, resource_class, verb = :get, statement = {}, connection)
20
20
  url = resource_url(rel)
21
+ payload = statement.empty? ? nil : statement
21
22
  response = case verb
22
23
  when :get then connection.get(url, payload)
23
24
  when :post then connection.post(url, payload)
@@ -26,9 +27,9 @@ module Neo4j
26
27
  response.status == 404 ? nil : resource_class.new(db, response, url, connection)
27
28
  end
28
29
 
29
- def resource_url(rel=nil)
30
- return @resource_url unless rel
31
- url = @resource_data[rel.to_s]
30
+ def resource_url(rel = nil)
31
+ return @resource_url if rel.nil?
32
+ url = resource_data[rel.to_s]
32
33
  raise "No resource rel '#{rel}', available #{@resource_data.keys.inspect}" unless url
33
34
  url
34
35
  end
@@ -51,7 +52,7 @@ module Neo4j
51
52
  {'Content-Type' => 'application/json', 'Accept' => 'application/json'}
52
53
  end
53
54
 
54
- def resource_url_id(url = @resource_url)
55
+ def resource_url_id(url = resource_url)
55
56
  url.match(/\/(\d+)$/)[1].to_i
56
57
  end
57
58
 
data/neo4j-core.gemspec CHANGED
@@ -10,16 +10,13 @@ Gem::Specification.new do |s|
10
10
 
11
11
  s.authors = "Andreas Ronge"
12
12
  s.email = 'andreas.ronge@gmail.com'
13
- s.homepage = "http://github.com/andreasronge/neo4j-core/tree"
13
+ s.homepage = "https://github.com/neo4jrb/neo4j-core"
14
14
  s.rubyforge_project = 'neo4j-core'
15
15
  s.summary = "A graph database for Ruby"
16
16
  s.license = 'MIT'
17
17
 
18
18
  s.description = <<-EOF
19
- You can think of Neo4j as a high-performance graph engine with all the features of a mature and robust database.
20
- The programmer works with an object-oriented, flexible network structure rather than with strict and static tables
21
- yet enjoys all the benefits of a fully transactional, enterprise-strength database.
22
- It comes included with the Apache Lucene document database.
19
+ Neo4j-core provides classes and methods to work with the graph database Neo4j.
23
20
  EOF
24
21
 
25
22
  s.require_path = 'lib'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Ronge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-26 00:00:00.000000000 Z
11
+ date: 2014-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -137,10 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  description: |
140
- You can think of Neo4j as a high-performance graph engine with all the features of a mature and robust database.
141
- The programmer works with an object-oriented, flexible network structure rather than with strict and static tables
142
- yet enjoys all the benefits of a fully transactional, enterprise-strength database.
143
- It comes included with the Apache Lucene document database.
140
+ Neo4j-core provides classes and methods to work with the graph database Neo4j.
144
141
  email: andreas.ronge@gmail.com
145
142
  executables: []
146
143
  extensions: []
@@ -190,7 +187,7 @@ files:
190
187
  - lib/neo4j/tasks/neo4j_server.rake
191
188
  - lib/neo4j/transaction.rb
192
189
  - neo4j-core.gemspec
193
- homepage: http://github.com/andreasronge/neo4j-core/tree
190
+ homepage: https://github.com/neo4jrb/neo4j-core
194
191
  licenses:
195
192
  - MIT
196
193
  metadata: {}