neo4j-core 3.0.0.rc.4 → 3.0.0.rc.5

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: 6f4e034ba33270fdcb1cb5b5535d039fd9efde54
4
- data.tar.gz: 532daaec0377fe3e610b2d76acd2b69a8f3c96e2
3
+ metadata.gz: b46b6f89a49ae652827b9c2b5dd687ec3e65180b
4
+ data.tar.gz: a830aa50a4fd7de437c9e3e80e5247ed0064bb9e
5
5
  SHA512:
6
- metadata.gz: 733e818958cc4ae6ad35d5a8c6a6d9a86e7d12c8117f35734c15520974cabb40deff43b25761d971fe78e19aa5b742b7105b463d5d584d91027a3bccd1f076fc
7
- data.tar.gz: 1d72fb9147c87fe03b6c9bc82aff383dad9fce34213da4020f5a7afbb840241e48006a16fb6d667725ba3c7a139fc80b396e671dfe6750d6ebaf9da512fbd83c
6
+ metadata.gz: a6bbd3ae59d56a28b15c19cd05fbb8ddd780bed3d90afc77c26e47d39a8a81a8e05a1823890cf4aa81caf241fa50bc6f49c9e6ce2054481c65db8c85c4d6f795
7
+ data.tar.gz: a93ed3d6e72c500b130c9fb6521f130376ffa6bc5818288be6d82383fc6d365f4637b00ede8f3a5a7911c09dca7e05b234278a9802626ac2f726d40eb1ecb1a1
data/Gemfile CHANGED
@@ -7,6 +7,9 @@ gem 'zip'
7
7
  #gem 'neo4j-advanced', '>= 1.8.1', '< 2.0', :require => false
8
8
  #gem 'neo4j-enterprise', '>= 1.8.1', '< 2.0', :require => false
9
9
 
10
+ gem 'coveralls', require: false
11
+ gem 'simplecov-html', require: false
12
+
10
13
  group 'development' do
11
14
  gem 'yard'
12
15
  gem 'simplecov'
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Neo4j-core v3.0 [![Code Climate](https://codeclimate.com/github/andreasronge/neo4j-core.png)](https://codeclimate.com/github/andreasronge/neo4j-core) [![Build Status](https://travis-ci.org/andreasronge/neo4j-core.png)](https://travis-ci.org/andreasronge/neo4j-core)
1
+ # Neo4j-core v3.0 [![Code Climate](https://codeclimate.com/github/andreasronge/neo4j-core.png)](https://codeclimate.com/github/andreasronge/neo4j-core) [![Build Status](https://travis-ci.org/neo4jrb/neo4j-core.png)](https://travis-ci.org/andreasronge/neo4j-core) [![Coverage Status](https://coveralls.io/repos/neo4jrb/neo4j-core/badge.png?branch=master)](https://coveralls.io/r/neo4jrb/neo4j-core?branch=master)
2
2
 
3
3
  A simple Ruby wrapper around the Neo4j graph database that works with the server and embedded Neo4j API. This gem can be used both from JRuby and normal MRI.
4
4
  It can be used standalone without the neo4j gem.
@@ -24,6 +24,7 @@ It can be used standalone without the neo4j gem.
24
24
  ## Contributing
25
25
 
26
26
  Pull request with high test coverage and good [code climate](https://codeclimate.com/github/andreasronge/neo4j-core) values will be accepted faster.
27
+ Notice, only JRuby can run all the tests (embedded and server db). To run tests with coverage: `rake coverage`.
27
28
 
28
29
  ## License
29
30
  * Neo4j.rb - MIT, see the LICENSE file http://github.com/andreasronge/neo4j-core/tree/master/LICENSE.
@@ -99,7 +99,7 @@ module Neo4j::Core
99
99
 
100
100
  METHODS = %w[with start match optional_match using where set create create_unique merge on_create_set on_match_set remove unwind delete return order skip limit]
101
101
 
102
- CLAUSES = METHODS.map {|method| const_get(method.split('_').map {|c| c.capitalize }.join + 'Clause') }
102
+ CLAUSES = METHODS.map { |method| const_get(method.split('_').map { |c| c.capitalize }.join + 'Clause') }
103
103
 
104
104
  METHODS.each_with_index do |clause, i|
105
105
  clause_class = CLAUSES[i]
@@ -145,7 +145,7 @@ module Neo4j::Core
145
145
  def response
146
146
  return @response if @response
147
147
  cypher = self.to_cypher
148
- @response = ActiveSupport::Notifications.instrument('neo4j.cypher_query', context: @options[:context] || 'CYPHER', cypher: cypher, params: @_params) do
148
+ @response = ActiveSupport::Notifications.instrument('neo4j.cypher_query', context: @options[:context] || 'CYPHER', cypher: cypher, params: merge_params) do
149
149
  @session._query(cypher, merge_params)
150
150
  end
151
151
  if !response.respond_to?(:error?) || !response.error?
@@ -163,7 +163,7 @@ module Neo4j::Core
163
163
  response.to_node_enumeration
164
164
  else
165
165
  Neo4j::Embedded::ResultWrapper.new(response, self.to_cypher)
166
- end.each {|object| yield object }
166
+ end.each { |object| yield object }
167
167
  end
168
168
 
169
169
  # @method to_a
@@ -191,19 +191,7 @@ module Neo4j::Core
191
191
  # Query.new.match(n: :Person).return(p: :name}.pluck('p, DISTINCT p.name') # => Array of [node, name] pairs
192
192
  #
193
193
  def pluck(*columns)
194
- query = self.dup
195
- query.remove_clause_class(ReturnClause)
196
-
197
- columns = columns.map do |column_definition|
198
- if column_definition.is_a?(Hash)
199
- column_definition.map {|k, v| "#{k}.#{v}" }
200
- else
201
- column_definition
202
- end
203
- end.flatten.map(&:to_sym)
204
-
205
- query = query.return(columns)
206
-
194
+ query = return_query(columns)
207
195
  columns = query.response.columns
208
196
 
209
197
  case columns.size
@@ -211,7 +199,7 @@ module Neo4j::Core
211
199
  raise ArgumentError, 'No columns specified for Query#pluck'
212
200
  when 1
213
201
  column = columns[0]
214
- query.map {|row| row[column] }
202
+ query.map { |row| row[column] }
215
203
  else
216
204
  query.map do |row|
217
205
  columns.map do |column|
@@ -221,6 +209,20 @@ module Neo4j::Core
221
209
  end
222
210
  end
223
211
 
212
+ def return_query(columns)
213
+ query = self.dup
214
+ query.remove_clause_class(ReturnClause)
215
+
216
+ columns = columns.map do |column_definition|
217
+ if column_definition.is_a?(Hash)
218
+ column_definition.map { |k, v| "#{k}.#{v}" }
219
+ else
220
+ column_definition
221
+ end
222
+ end.flatten.map(&:to_sym)
223
+
224
+ query.return(columns)
225
+ end
224
226
 
225
227
  # Returns a CYPHER query string from the object query representation
226
228
  # @example
@@ -310,11 +312,8 @@ module Neo4j::Core
310
312
  end
311
313
 
312
314
  def merge_params
313
- @clauses.compact.inject(@_params) {|params, clause| params.merge(clause.params) }
315
+ @merge_params ||= @clauses.compact.inject(@_params) { |params, clause| params.merge(clause.params) }
314
316
  end
315
317
 
316
318
  end
317
319
  end
318
-
319
-
320
-
@@ -112,6 +112,17 @@ module Neo4j::Core
112
112
 
113
113
  private
114
114
 
115
+ def key_value_string(key, value, previous_keys = [], force_equals = false)
116
+ param = (previous_keys + [key]).join('_').gsub(/[\(\)\._]+/, '_')
117
+ @params[param.to_sym] = value
118
+
119
+ if !value.is_a?(Array) || force_equals
120
+ "#{key} = {#{param}}"
121
+ else
122
+ "#{key} IN {#{param}}"
123
+ end
124
+ end
125
+
115
126
  def format_label(label_string)
116
127
  label_string = label_string.to_s.strip
117
128
  if !label_string.empty? && label_string[0] != ':'
@@ -184,19 +195,6 @@ module Neo4j::Core
184
195
  clauses.map(&:value).join(' AND ')
185
196
  end
186
197
  end
187
-
188
- private
189
-
190
- def key_value_string(key, value, previous_keys = [])
191
- param = (previous_keys + [key]).join('_').gsub(/[\(\)\._]+/, '_')
192
- @params = @params.merge(param.to_sym => value)
193
-
194
- if value.is_a?(Array)
195
- "#{key} IN {#{param}}"
196
- else
197
- "#{key} = {#{param}}"
198
- end
199
- end
200
198
  end
201
199
 
202
200
 
@@ -386,7 +384,7 @@ module Neo4j::Core
386
384
  "#{key} = {#{attribute_string}}"
387
385
  else
388
386
  value.map do |k, v|
389
- "#{key}.#{k} = #{v.inspect}"
387
+ key_value_string("#{key}.#{k}", v, ['setter'], true)
390
388
  end
391
389
  end
392
390
  else
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Core
3
- VERSION = "3.0.0.rc.4"
3
+ VERSION = "3.0.0.rc.5"
4
4
  end
5
5
  end
@@ -0,0 +1,21 @@
1
+ require 'neo4j-enterprise'
2
+
3
+ Neo4j::Session.register_db(:ha_db) do |*args|
4
+ Neo4j::Embedded::EmbeddedHaSession.new(*args)
5
+ end
6
+
7
+ module Neo4j::Embedded
8
+ class EmbeddedHaSession < EmbeddedSession
9
+ def start
10
+ raise Error.new("Embedded HA Neo4j db is already running") if running?
11
+ puts "Start embedded HA Neo4j db at #{db_location}"
12
+ factory = Java::OrgNeo4jGraphdbFactory::HighlyAvailableGraphDatabaseFactory.new
13
+ db_service = factory.newHighlyAvailableDatabaseBuilder(db_location)
14
+
15
+ raise Error.new("Need properties file for HA configuration") unless properties_file
16
+ db_service.loadPropertiesFromFile(properties_file)
17
+ @graph_db = db_service.newGraphDatabase()
18
+ Neo4j::Session._notify_listeners(:session_available, self)
19
+ end
20
+ end
21
+ end
@@ -53,6 +53,18 @@ module Neo4j::Embedded
53
53
  end
54
54
  tx_methods :indexes
55
55
 
56
+ def uniqueness_constraints()
57
+ {
58
+ property_keys: @session.graph_db.schema.constraints(as_java).select do |index_def|
59
+ index_def.is_a?(Java::OrgNeo4jKernelImplCoreapiSchema::PropertyUniqueConstraintDefinition)
60
+ end.map do |index_def|
61
+ index_def.property_keys.map{|x| x.to_sym}
62
+ end
63
+ }
64
+ end
65
+ tx_methods :uniqueness_constraints
66
+
67
+
56
68
  def drop_index(*properties)
57
69
  @session.graph_db.schema.indexes(as_java).each do |index_def|
58
70
  # at least one match, TODO
@@ -11,15 +11,16 @@ module Neo4j::Embedded
11
11
  class Error < StandardError
12
12
  end
13
13
 
14
- attr_reader :graph_db, :db_location
14
+ attr_reader :graph_db, :db_location, :properties_file
15
15
  extend Forwardable
16
16
  extend Neo4j::Core::TxMethods
17
17
  def_delegator :@graph_db, :begin_tx
18
18
 
19
19
 
20
20
  def initialize(db_location, config={})
21
- @db_location = db_location
22
- @auto_commit = !!config[:auto_commit]
21
+ @db_location = db_location
22
+ @auto_commit = !!config[:auto_commit]
23
+ @properties_file = config[:properties_file]
23
24
  Neo4j::Session.register(self)
24
25
  end
25
26
 
@@ -34,8 +35,10 @@ module Neo4j::Embedded
34
35
  def start
35
36
  raise Error.new("Embedded Neo4j db is already running") if running?
36
37
  puts "Start embedded Neo4j db at #{db_location}"
37
- factory = Java::OrgNeo4jGraphdbFactory::GraphDatabaseFactory.new
38
- @graph_db = factory.newEmbeddedDatabase(db_location)
38
+ factory = Java::OrgNeo4jGraphdbFactory::GraphDatabaseFactory.new
39
+ db_service = factory.newEmbeddedDatabaseBuilder(db_location)
40
+ db_service.loadPropertiesFromFile(properties_file) if properties_file
41
+ @graph_db = db_service.newGraphDatabase()
39
42
  Neo4j::Session._notify_listeners(:session_available, self)
40
43
  @engine = Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(@graph_db)
41
44
  end
@@ -80,8 +80,6 @@ module Neo4j::Embedded::Property
80
80
  remove_property(k)
81
81
  elsif (Array === v)
82
82
  case v[0]
83
- when NilClass
84
- set_property(k, [].to_java(:string))
85
83
  when String
86
84
  set_property(k, v.to_java(:string))
87
85
  when Float
data/lib/neo4j-server.rb CHANGED
@@ -1,6 +1,6 @@
1
- require 'httparty'
2
1
  require 'json'
3
- require 'neo4j-server/neo4j_server_endpoint'
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
4
  require 'neo4j-server/resource'
5
5
  require 'neo4j-server/cypher_node'
6
6
  require 'neo4j-server/cypher_label'
@@ -24,5 +24,9 @@ module Neo4j::Server
24
24
  def indexes
25
25
  @session.indexes(@name)
26
26
  end
27
+
28
+ def uniqueness_constraints
29
+ @session.uniqueness_constraints(@name)
30
+ end
27
31
  end
28
- end
32
+ end
@@ -117,7 +117,7 @@ module Neo4j::Server
117
117
  end
118
118
 
119
119
  def raise_unless_response_code(code)
120
- raise "Response code #{response.code}, expected #{code} for #{response.request.path}, #{response.body}" unless response.code == code
120
+ raise "Response code #{response.code}, expected #{code} for #{response.request.path}, #{response.body}" unless response.status == code
121
121
  end
122
122
 
123
123
  def each_data_row
@@ -155,26 +155,26 @@ module Neo4j::Server
155
155
 
156
156
 
157
157
  def self.create_with_no_tx(response)
158
- case response.code
158
+ case response.status
159
159
  when 200
160
- CypherResponse.new(response).set_data(response['data'], response['columns'])
160
+ CypherResponse.new(response).set_data(response.body['data'], response.body['columns'])
161
161
  when 400
162
- CypherResponse.new(response).set_error(response['message'], response['exception'], response['fullname'])
162
+ CypherResponse.new(response).set_error(response.body['message'], response.body['exception'], response.body['fullname'])
163
163
  else
164
- raise "Unknown response code #{response.code} for #{response.request.path.to_s}"
164
+ raise "Unknown response code #{response.status} for #{response.env[:url].to_s}"
165
165
  end
166
166
  end
167
167
 
168
168
  def self.create_with_tx(response)
169
- raise "Unknown response code #{response.code} for #{response.request.path.to_s}" unless response.code == 200
169
+ raise "Unknown response code #{response.status} for #{response.request_uri}" unless response.status == 200
170
170
 
171
- first_result = response['results'][0]
171
+ first_result = response.body['results'][0]
172
172
  cr = CypherResponse.new(response, true)
173
173
 
174
- if (response['errors'].empty?)
174
+ if (response.body['errors'].empty?)
175
175
  cr.set_data(first_result['data'], first_result['columns'])
176
176
  else
177
- first_error = response['errors'].first
177
+ first_error = response.body['errors'].first
178
178
  cr.set_error(first_error['message'], first_error['status'], first_error['code'])
179
179
  end
180
180
  cr
@@ -10,28 +10,46 @@ module Neo4j::Server
10
10
  include Neo4j::Core::CypherTranslator
11
11
 
12
12
  alias_method :super_query, :query
13
-
13
+ attr_reader :connection
14
+
15
+ # @param [Hash] params could be empty or contain basic authentication user and password
16
+ # @return [Faraday]
17
+ # @see https://github.com/lostisland/faraday
18
+ def self.create_connection(params)
19
+ init_params = params[:initialize] and params.delete(:initialize)
20
+ conn = Faraday.new(init_params) do |b|
21
+ b.request :basic_auth, params[:basic_auth][:username], params[:basic_auth][:password] if params[:basic_auth]
22
+ b.request :json
23
+ #b.response :logger
24
+ b.response :json, :content_type => "application/json"
25
+ #b.use Faraday::Response::RaiseError
26
+ b.use Faraday::Adapter::NetHttpPersistent
27
+ # b.adapter Faraday.default_adapter
28
+ end
29
+ conn.headers = {'Content-Type' => 'application/json'}
30
+ conn
31
+ end
14
32
 
15
33
  # Opens a session to the database
16
34
  # @see Neo4j::Session#open
17
35
  #
18
36
  # @param [String] endpoint_url - the url to the neo4j server, defaults to 'http://localhost:7474'
19
- # @param [Hash] params - see https://github.com/jnunemaker/httparty/blob/master/lib/httparty.rb for supported HTTParty options
37
+ # @param [Hash] params faraday params, see #create_connection or an already created faraday connection
20
38
  def self.open(endpoint_url=nil, params = {})
21
- endpoint = Neo4jServerEndpoint.new(params)
39
+ connection = params[:connection] || create_connection(params)
22
40
  url = endpoint_url || 'http://localhost:7474'
23
- response = endpoint.get(url)
24
- raise "Server not available on #{url} (response code #{response.code})" unless response.code == 200
25
-
26
- root_data = JSON.parse(response.body)
41
+ response = connection.get(url)
42
+ raise "Server not available on #{url} (response code #{response.status})" unless response.status == 200
43
+
44
+ root_data = response.body
27
45
  data_url = root_data['data']
28
46
  data_url << '/' unless data_url.end_with?('/')
29
47
 
30
- CypherSession.new(data_url, endpoint)
48
+ CypherSession.new(data_url, connection)
31
49
  end
32
50
 
33
- def initialize(data_url, endpoint = nil)
34
- @endpoint = endpoint || Neo4jServerEndpoint.new(data_url)
51
+ def initialize(data_url, connection)
52
+ @connection = connection
35
53
  Neo4j::Session.register(self)
36
54
  initialize_resource(data_url)
37
55
  Neo4j::Session._notify_listeners(:session_available, self)
@@ -54,9 +72,9 @@ module Neo4j::Server
54
72
  end
55
73
 
56
74
  def initialize_resource(data_url)
57
- response = @endpoint.get(data_url)
75
+ response = @connection.get(data_url)
58
76
  expect_response_code(response,200)
59
- data_resource = JSON.parse(response.body)
77
+ data_resource = response.body
60
78
  raise "No data_resource for #{response.body}" unless data_resource
61
79
  # store the resource data
62
80
  init_resource_data(data_resource, data_url)
@@ -72,7 +90,7 @@ module Neo4j::Server
72
90
  # Handle nested transaction "placebo transaction"
73
91
  Neo4j::Transaction.current.push_nested!
74
92
  else
75
- wrap_resource(self, 'transaction', CypherTransaction, nil, :post, @endpoint)
93
+ wrap_resource(self, 'transaction', CypherTransaction, :post, @connection)
76
94
  end
77
95
  Neo4j::Transaction.current
78
96
  end
@@ -111,10 +129,24 @@ module Neo4j::Server
111
129
  CypherLabel.new(self, name)
112
130
  end
113
131
 
132
+ def uniqueness_constraints(label)
133
+ response = @connection.get("#{@resource_url}schema/constraint/#{label}/uniqueness")
134
+ expect_response_code(response, 200)
135
+ data_resource = response.body
136
+
137
+ property_keys = data_resource.map do |row|
138
+ row['property_keys'].map(&:to_sym)
139
+ end
140
+
141
+ {
142
+ property_keys: property_keys
143
+ }
144
+ end
145
+
114
146
  def indexes(label)
115
- response = @endpoint.get("#{@resource_url}schema/index/#{label}")
147
+ response = @connection.get("#{@resource_url}schema/index/#{label}")
116
148
  expect_response_code(response, 200)
117
- data_resource = JSON.parse(response.body)
149
+ data_resource = response.body
118
150
 
119
151
  property_keys = data_resource.map do |row|
120
152
  row['property_keys'].map(&:to_sym)
@@ -142,9 +174,11 @@ module Neo4j::Server
142
174
  end
143
175
 
144
176
  def query(*args)
145
- if [[String], [String, String]].include?(args.map(&:class))
177
+ if [[String], [String, Hash]].include?(args.map(&:class))
146
178
  query, params = args[0,2]
147
- _query(query, params).to_node_enumeration(query)
179
+ response = _query(query, params)
180
+ response.raise_error if response.error?
181
+ response.to_node_enumeration(query)
148
182
  else
149
183
  options = args[0] || {}
150
184
  Neo4j::Core::Query.new(options.merge(session: self))
@@ -175,21 +209,38 @@ module Neo4j::Server
175
209
  curr_tx._query(q, params)
176
210
  else
177
211
  url = resource_url('cypher')
178
- q = params.nil? ? {query: q} : {query: q, params: params}
179
- response = @endpoint.post(url, headers: resource_headers, body: q.to_json)
212
+ q = params.nil? ? { 'query' => q } : { 'query' => q, 'params' => params}
213
+ response = @connection.post(url, q)
180
214
  CypherResponse.create_with_no_tx(response)
181
215
  end
182
216
  end
183
217
 
184
218
  def search_result_to_enumerable_first_column(response)
185
219
  return [] unless response.data
220
+ if Neo4j::Transaction.current
221
+ search_result_to_enumerable_first_column_with_tx(response)
222
+ else
223
+ search_result_to_enumerable_first_column_without_tx(response)
224
+ end
225
+ end
226
+
227
+ def search_result_to_enumerable_first_column_with_tx(response)
186
228
  Enumerator.new do |yielder|
187
229
  response.data.each do |data|
188
- yielder << CypherNode.new(self, data[0]).wrapper
230
+ data["row"].each do |id|
231
+ yielder << CypherNode.new(self, id).wrapper
232
+ end
189
233
  end
190
234
  end
191
235
  end
192
236
 
237
+ def search_result_to_enumerable_first_column_without_tx(response)
238
+ Enumerator.new do |yielder|
239
+ response.data.each do |data|
240
+ yielder << CypherNode.new(self, data[0]).wrapper
241
+ end
242
+ end
243
+ end
193
244
 
194
245
  def map_column(key, map, data)
195
246
  case map[key]
@@ -15,11 +15,12 @@ module Neo4j::Server
15
15
  end
16
16
  end
17
17
 
18
- def initialize(db, response, url, endpoint)
19
- @endpoint = endpoint
20
- @commit_url = response['commit']
21
- @exec_url = response.headers['location']
22
- init_resource_data(response, url)
18
+ def initialize(db, response, url, connection)
19
+ @connection = connection
20
+ @commit_url = response.body['commit']
21
+ @exec_url = response.headers['Location']
22
+ raise "NO ENDPOINT URL #{@connection} : HEAD: #{response.headers.inspect}" if !@exec_url || @exec_url.empty?
23
+ init_resource_data(response.body, url)
23
24
  expect_response_code(response,201)
24
25
  register_instance
25
26
  end
@@ -41,18 +42,18 @@ module Neo4j::Server
41
42
  statement[:statement].gsub!("{ #{k} }", "#{escape_value(v)}")
42
43
  end
43
44
  end
44
- response = @endpoint.post(@exec_url, headers: resource_headers, body: body.to_json)
45
+ response = @connection.post(@exec_url, body)
45
46
  _create_cypher_response(response)
46
47
  end
47
48
 
48
49
  def _create_cypher_response(response)
49
- first_result = response['results'][0]
50
+ first_result = response.body['results'][0]
50
51
  cr = CypherResponse.new(response, true)
51
52
 
52
- if (response['errors'].empty?)
53
+ if (response.body['errors'].empty?)
53
54
  cr.set_data(first_result['data'], first_result['columns'])
54
55
  else
55
- first_error = response['errors'].first
56
+ first_error = response.body['errors'].first
56
57
  cr.set_error(first_error['message'], first_error['code'], first_error['code'])
57
58
  end
58
59
  cr
@@ -61,13 +62,14 @@ module Neo4j::Server
61
62
 
62
63
 
63
64
  def _delete_tx
64
- response = @endpoint.delete(@exec_url, headers: resource_headers)
65
+ response = @connection.delete(@exec_url, headers: resource_headers)
65
66
  expect_response_code(response,200)
66
67
  response
67
68
  end
68
69
 
69
70
  def _commit_tx
70
- response = @endpoint.post(@commit_url, headers: resource_headers)
71
+ response = @connection.post(@commit_url)
72
+
71
73
  expect_response_code(response,200)
72
74
  response
73
75
  end
@@ -8,7 +8,7 @@ module Neo4j
8
8
  attr_reader :resource_data, :resource_url
9
9
 
10
10
  def init_resource_data(resource_data, resource_url)
11
- raise "Exception #{response['exception']}" if resource_data['exception']
11
+ raise "Exception #{resource_data['exception']}" if resource_data['exception']
12
12
  @resource_url = resource_url
13
13
  @resource_data = resource_data
14
14
  raise "expected @resource_data to be Hash got #{@resource_data.class}" unless @resource_data.respond_to?(:[])
@@ -16,30 +16,29 @@ module Neo4j
16
16
  end
17
17
 
18
18
 
19
- def wrap_resource(db, rel, resource_class, args=nil, verb=:get, payload=nil, endpoint)
20
- url = resource_url(rel, args)
21
- response = endpoint.send(verb, url, headers: {'Content-Type' => 'application/json'}, body: payload)
22
- response.code == 404 ? nil : resource_class.new(db, response, url, endpoint)
19
+ def wrap_resource(db, rel, resource_class, verb=:get, payload={}, connection)
20
+ url = resource_url(rel)
21
+ response = case verb
22
+ when :get then connection.get(url, payload)
23
+ when :post then connection.post(url, payload)
24
+ else raise "Illegal verb #{verb}"
25
+ end
26
+ response.status == 404 ? nil : resource_class.new(db, response, url, connection)
23
27
  end
24
28
 
25
- def resource_url(rel=nil, args=nil)
29
+ def resource_url(rel=nil)
26
30
  return @resource_url unless rel
27
31
  url = @resource_data[rel.to_s]
28
32
  raise "No resource rel '#{rel}', available #{@resource_data.keys.inspect}" unless url
29
- return url unless args
30
- if (args.is_a?(Hash))
31
- args.keys.inject(url){|ack, key| ack.sub("{#{key}}",args[key].to_s)}
32
- else
33
- "#{url}/#{args.to_s}"
34
- end
33
+ url
35
34
  end
36
35
 
37
- def handle_response_error(response, msg="Error for request", url = response.request.path.to_s )
38
- raise ServerException.new("#{msg} #{url}, #{response.code}, #{response.body}")
36
+ def handle_response_error(response, msg="Error for request" )
37
+ raise ServerException.new("#{msg} #{response.env && response.env[:url].to_s}, #{response.status}, #{response.status}")
39
38
  end
40
39
 
41
- def expect_response_code(response, expected_code, msg="Error for request", url=response.request.path.to_s )
42
- handle_response_error(response, "Expected response code #{expected_code} #{msg}",url) unless response.code == expected_code
40
+ def expect_response_code(response, expected_code, msg="Error for request" )
41
+ handle_response_error(response, "Expected response code #{expected_code} #{msg}") unless response.status == expected_code
43
42
  response
44
43
  end
45
44
 
@@ -59,15 +58,6 @@ module Neo4j
59
58
  def convert_from_json_value(value)
60
59
  JSON.parse(value, :quirks_mode => true)
61
60
  end
62
-
63
- def convert_to_json_value(value)
64
- case value
65
- when String
66
- %Q["#{value}"]
67
- else
68
- value.to_s
69
- end
70
- end
71
61
  end
72
62
  end
73
63
  end
data/lib/neo4j/session.rb CHANGED
@@ -78,7 +78,21 @@ module Neo4j
78
78
  end
79
79
 
80
80
  class << self
81
- # Creates a new session to Neo4j
81
+ # Creates a new session to Neo4j.
82
+ # This will be the default session to be used unless there is already a session created (see #current and #set_current)
83
+ #
84
+ # @example A Neo4j Server session
85
+ # Neo4j::Session.open(:server_db, 'http://localhost:7474', {basic_auth: {username: 'foo', password: 'bar'}})
86
+ #
87
+ # @example Using a user defined Faraday HTTP connection
88
+ # connection = Faraday.new do |b|
89
+ # # faraday config
90
+ # end
91
+ # Neo4j::Session.open(:server_db, 'http://localhost:7474', connection: connection)
92
+ #
93
+ # @example A embedded Neo4j session
94
+ # Neo4j::Session.open(:embedded_db, 'path/to/db')
95
+ #
82
96
  # @see also Neo4j::Server::CypherSession#open for :server_db params
83
97
  # @param db_type the type of database, e.g. :embedded_db, or :server_db
84
98
  def open(db_type=:server_db, *params)
@@ -90,6 +104,7 @@ module Neo4j
90
104
  register(create_session(db_type, params), name, default)
91
105
  end
92
106
 
107
+ # @private
93
108
  def create_session(db_type, params = {})
94
109
  unless (@@factories[db_type])
95
110
  raise "Can't connect to database '#{db_type}', available #{@@factories.keys.join(',')}"
@@ -97,24 +112,29 @@ module Neo4j
97
112
  @@factories[db_type].call(*params)
98
113
  end
99
114
 
115
+ # @return [Neo4j::Session] the current session
100
116
  def current
101
117
  @@current_session
102
118
  end
103
119
 
120
+ # Returns the current session or raise an exception if no session is available
104
121
  def current!
105
122
  raise "No session, please create a session first with Neo4j::Session.open(:server_db) or :embedded_db" unless current
106
123
  current
107
124
  end
108
125
 
109
126
  # @see Neo4j::Session#query
110
- def query(options = {})
111
- current!.query(options)
127
+ def query(*args)
128
+ current!.query(*args)
112
129
  end
113
130
 
131
+ # Returns a session with given name or else raise an exception
114
132
  def named(name)
115
133
  @@all_sessions[name] || raise("No session named #{name}.")
116
134
  end
117
135
 
136
+ # Sets the session to be used as default
137
+ # @param [Neo4j::Session] session the session to use
118
138
  def set_current(session)
119
139
  @@current_session = session
120
140
  end
@@ -130,19 +150,23 @@ module Neo4j
130
150
  end
131
151
  end
132
152
 
153
+ # @private
133
154
  def add_listener(&listener)
134
155
  self._listeners << listener
135
156
  end
136
157
 
158
+ # @private
137
159
  def _listeners
138
160
  @@listeners ||= []
139
161
  @@listeners
140
162
  end
141
163
 
164
+ # @private
142
165
  def _notify_listeners(event, data)
143
166
  _listeners.each {|li| li.call(event, data)}
144
167
  end
145
168
 
169
+ # @private
146
170
  def register(session, name = nil, default = nil)
147
171
  if default == true
148
172
  set_current(session)
@@ -150,9 +174,10 @@ module Neo4j
150
174
  set_current(session) unless @@current_session
151
175
  end
152
176
  @@all_sessions[name] = session if name
153
- @@current_session
177
+ session
154
178
  end
155
179
 
180
+ # @private
156
181
  def unregister(session)
157
182
  @@current_session = nil if @@current_session == session
158
183
  end
@@ -161,6 +186,7 @@ module Neo4j
161
186
  "Neo4j::Session available: #{@@factories && @@factories.keys}"
162
187
  end
163
188
 
189
+ # @private
164
190
  def register_db(db, &session_factory)
165
191
  puts "replace factory for #{db}" if @@factories[db]
166
192
  @@factories[db] = session_factory
@@ -2,6 +2,7 @@
2
2
  require 'os'
3
3
  require 'httparty'
4
4
  require 'zip'
5
+ require 'httparty'
5
6
  require File.expand_path("../config_server", __FILE__)
6
7
 
7
8
  namespace :neo4j do
data/neo4j-core.gemspec CHANGED
@@ -30,6 +30,10 @@ It comes included with the Apache Lucene document database.
30
30
 
31
31
  # Not released yet
32
32
  s.add_dependency("httparty")
33
+ s.add_dependency("faraday", '~> 0.9.0')
34
+ s.add_dependency('net-http-persistent')
35
+ s.add_dependency('httpclient')
36
+ s.add_dependency('faraday_middleware', '~> 0.9.1')
33
37
  s.add_dependency("json")
34
38
  s.add_dependency("os") # for Rake task
35
39
  s.add_dependency("zip") # for Rake task
@@ -37,5 +41,6 @@ It comes included with the Apache Lucene document database.
37
41
 
38
42
  if RUBY_PLATFORM == 'java'
39
43
  s.add_dependency("neo4j-community", '~> 2.1.1')
44
+ s.add_development_dependency 'ruby-debug'
40
45
  end
41
46
  end
metadata CHANGED
@@ -1,99 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc.4
4
+ version: 3.0.0.rc.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Ronge
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-27 00:00:00.000000000 Z
11
+ date: 2014-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
15
22
  version_requirements: !ruby/object:Gem::Requirement
16
23
  requirements:
17
- - - '>='
24
+ - - ">="
18
25
  - !ruby/object:Gem::Version
19
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
20
29
  requirement: !ruby/object:Gem::Requirement
21
30
  requirements:
22
- - - '>='
31
+ - - "~>"
23
32
  - !ruby/object:Gem::Version
24
- version: '0'
25
- prerelease: false
33
+ version: 0.9.0
26
34
  type: :runtime
27
- - !ruby/object:Gem::Dependency
28
- name: json
35
+ prerelease: false
29
36
  version_requirements: !ruby/object:Gem::Requirement
30
37
  requirements:
31
- - - '>='
38
+ - - "~>"
32
39
  - !ruby/object:Gem::Version
33
- version: '0'
40
+ version: 0.9.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-http-persistent
34
43
  requirement: !ruby/object:Gem::Requirement
35
44
  requirements:
36
- - - '>='
45
+ - - ">="
37
46
  - !ruby/object:Gem::Version
38
47
  version: '0'
39
- prerelease: false
40
48
  type: :runtime
41
- - !ruby/object:Gem::Dependency
42
- name: os
49
+ prerelease: false
43
50
  version_requirements: !ruby/object:Gem::Requirement
44
51
  requirements:
45
- - - '>='
52
+ - - ">="
46
53
  - !ruby/object:Gem::Version
47
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: httpclient
48
57
  requirement: !ruby/object:Gem::Requirement
49
58
  requirements:
50
- - - '>='
59
+ - - ">="
51
60
  - !ruby/object:Gem::Version
52
61
  version: '0'
62
+ type: :runtime
53
63
  prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday_middleware
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.1
54
76
  type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.1
55
83
  - !ruby/object:Gem::Dependency
56
- name: zip
84
+ name: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
57
92
  version_requirements: !ruby/object:Gem::Requirement
58
93
  requirements:
59
- - - '>='
94
+ - - ">="
60
95
  - !ruby/object:Gem::Version
61
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: os
62
99
  requirement: !ruby/object:Gem::Requirement
63
100
  requirements:
64
- - - '>='
101
+ - - ">="
65
102
  - !ruby/object:Gem::Version
66
103
  version: '0'
67
- prerelease: false
68
104
  type: :runtime
69
- - !ruby/object:Gem::Dependency
70
- name: activesupport
105
+ prerelease: false
71
106
  version_requirements: !ruby/object:Gem::Requirement
72
107
  requirements:
73
- - - '>='
108
+ - - ">="
74
109
  - !ruby/object:Gem::Version
75
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: zip
76
113
  requirement: !ruby/object:Gem::Requirement
77
114
  requirements:
78
- - - '>='
115
+ - - ">="
79
116
  - !ruby/object:Gem::Version
80
117
  version: '0'
81
- prerelease: false
82
118
  type: :runtime
83
- - !ruby/object:Gem::Dependency
84
- name: neo4j-community
119
+ prerelease: false
85
120
  version_requirements: !ruby/object:Gem::Requirement
86
121
  requirements:
87
- - - ~>
122
+ - - ">="
88
123
  - !ruby/object:Gem::Version
89
- version: 2.1.1
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
90
127
  requirement: !ruby/object:Gem::Requirement
91
128
  requirements:
92
- - - ~>
129
+ - - ">="
93
130
  - !ruby/object:Gem::Version
94
- version: 2.1.1
95
- prerelease: false
131
+ version: '0'
96
132
  type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  description: |
98
140
  You can think of Neo4j as a high-performance graph engine with all the features of a mature and robust database.
99
141
  The programmer works with an object-oriented, flexible network structure rather than with strict and static tables
@@ -105,19 +147,9 @@ extensions: []
105
147
  extra_rdoc_files:
106
148
  - README.md
107
149
  files:
150
+ - Gemfile
151
+ - README.md
108
152
  - lib/neo4j-core.rb
109
- - lib/neo4j-embedded.rb
110
- - lib/neo4j-server.rb
111
- - lib/neo4j/entity_equality.rb
112
- - lib/neo4j/label.rb
113
- - lib/neo4j/node.rb
114
- - lib/neo4j/property_container.rb
115
- - lib/neo4j/property_validator.rb
116
- - lib/neo4j/relationship.rb
117
- - lib/neo4j/session.rb
118
- - lib/neo4j/transaction.rb
119
- - lib/neo4j/tasks/config_server.rb
120
- - lib/neo4j/tasks/neo4j_server.rb
121
153
  - lib/neo4j-core/active_entity.rb
122
154
  - lib/neo4j-core/cypher_translator.rb
123
155
  - lib/neo4j-core/hash_with_indifferent_access.rb
@@ -126,8 +158,10 @@ files:
126
158
  - lib/neo4j-core/query.rb
127
159
  - lib/neo4j-core/query_clauses.rb
128
160
  - lib/neo4j-core/version.rb
161
+ - lib/neo4j-embedded.rb
129
162
  - lib/neo4j-embedded/cypher_response.rb
130
163
  - lib/neo4j-embedded/embedded_database.rb
164
+ - lib/neo4j-embedded/embedded_ha_session.rb
131
165
  - lib/neo4j-embedded/embedded_impermanent_session.rb
132
166
  - lib/neo4j-embedded/embedded_label.rb
133
167
  - lib/neo4j-embedded/embedded_node.rb
@@ -136,6 +170,7 @@ files:
136
170
  - lib/neo4j-embedded/embedded_transaction.rb
137
171
  - lib/neo4j-embedded/property.rb
138
172
  - lib/neo4j-embedded/to_java.rb
173
+ - lib/neo4j-server.rb
139
174
  - lib/neo4j-server/cypher_label.rb
140
175
  - lib/neo4j-server/cypher_node.rb
141
176
  - lib/neo4j-server/cypher_node_uncommited.rb
@@ -143,40 +178,47 @@ files:
143
178
  - lib/neo4j-server/cypher_response.rb
144
179
  - lib/neo4j-server/cypher_session.rb
145
180
  - lib/neo4j-server/cypher_transaction.rb
146
- - lib/neo4j-server/neo4j_server_endpoint.rb
147
181
  - lib/neo4j-server/resource.rb
148
- - README.md
149
- - Gemfile
182
+ - lib/neo4j/entity_equality.rb
183
+ - lib/neo4j/label.rb
184
+ - lib/neo4j/node.rb
185
+ - lib/neo4j/property_container.rb
186
+ - lib/neo4j/property_validator.rb
187
+ - lib/neo4j/relationship.rb
188
+ - lib/neo4j/session.rb
189
+ - lib/neo4j/tasks/config_server.rb
190
+ - lib/neo4j/tasks/neo4j_server.rake
191
+ - lib/neo4j/transaction.rb
150
192
  - neo4j-core.gemspec
151
193
  homepage: http://github.com/andreasronge/neo4j-core/tree
152
194
  licenses:
153
195
  - MIT
154
196
  metadata: {}
155
- post_install_message:
197
+ post_install_message:
156
198
  rdoc_options:
157
- - --quiet
158
- - --title
199
+ - "--quiet"
200
+ - "--title"
159
201
  - Neo4j::Core
160
- - --line-numbers
161
- - --main
202
+ - "--line-numbers"
203
+ - "--main"
162
204
  - README.rdoc
163
- - --inline-source
205
+ - "--inline-source"
164
206
  require_paths:
165
207
  - lib
166
208
  required_ruby_version: !ruby/object:Gem::Requirement
167
209
  requirements:
168
- - - '>='
210
+ - - ">="
169
211
  - !ruby/object:Gem::Version
170
212
  version: 1.8.7
171
213
  required_rubygems_version: !ruby/object:Gem::Requirement
172
214
  requirements:
173
- - - '>'
215
+ - - ">"
174
216
  - !ruby/object:Gem::Version
175
217
  version: 1.3.1
176
218
  requirements: []
177
219
  rubyforge_project: neo4j-core
178
- rubygems_version: 2.1.9
179
- signing_key:
220
+ rubygems_version: 2.2.2
221
+ signing_key:
180
222
  specification_version: 4
181
223
  summary: A graph database for Ruby
182
224
  test_files: []
@@ -1,24 +0,0 @@
1
- module Neo4j::Server
2
- class Neo4jServerEndpoint
3
- def initialize(params = {})
4
- @params = params
5
- end
6
-
7
- def merged_options(options)
8
- options.merge!(@params)
9
- end
10
-
11
- def get(url, options={})
12
- HTTParty.get(url, merged_options(options))
13
- end
14
-
15
- def post(url, options={})
16
- HTTParty.post(url, merged_options(options))
17
- end
18
-
19
- def delete(url, options={})
20
- HTTParty.delete(url, merged_options(options))
21
- end
22
-
23
- end
24
- end