neo4j-core 8.1.4 → 9.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +71 -8
- data/lib/neo4j-core.rb +3 -49
- data/lib/neo4j/core.rb +4 -0
- data/lib/neo4j/core/config.rb +13 -0
- data/lib/neo4j/core/cypher_session/adaptors.rb +15 -15
- data/lib/neo4j/core/cypher_session/adaptors/bolt.rb +39 -48
- data/lib/neo4j/core/cypher_session/adaptors/bolt/chunk_writer_io.rb +0 -4
- data/lib/neo4j/core/cypher_session/adaptors/bolt/pack_stream.rb +7 -3
- data/lib/neo4j/core/cypher_session/adaptors/embedded.rb +1 -2
- data/lib/neo4j/core/cypher_session/adaptors/has_uri.rb +4 -0
- data/lib/neo4j/core/cypher_session/adaptors/http.rb +1 -3
- data/lib/neo4j/core/cypher_session/responses.rb +1 -1
- data/lib/neo4j/core/cypher_session/responses/bolt.rb +0 -17
- data/lib/neo4j/core/cypher_session/responses/embedded.rb +9 -7
- data/lib/neo4j/core/cypher_session/responses/http.rb +3 -4
- data/lib/neo4j/core/cypher_session/transactions.rb +2 -0
- data/lib/{neo4j-core → neo4j/core}/helpers.rb +1 -14
- data/lib/neo4j/core/logging.rb +44 -0
- data/lib/{neo4j-core → neo4j/core}/query.rb +7 -6
- data/lib/{neo4j-core → neo4j/core}/query_clauses.rb +9 -16
- data/lib/{neo4j-core → neo4j/core}/query_find_in_batches.rb +3 -5
- data/lib/{neo4j-core → neo4j/core}/version.rb +1 -1
- data/lib/neo4j/transaction.rb +6 -8
- data/neo4j-core.gemspec +13 -11
- metadata +46 -50
- data/lib/ext/kernel.rb +0 -9
- data/lib/neo4j-core/active_entity.rb +0 -11
- data/lib/neo4j-core/label.rb +0 -9
- data/lib/neo4j-embedded.rb +0 -16
- data/lib/neo4j-embedded/cypher_response.rb +0 -71
- data/lib/neo4j-embedded/embedded_database.rb +0 -26
- data/lib/neo4j-embedded/embedded_ha_session.rb +0 -30
- data/lib/neo4j-embedded/embedded_impermanent_session.rb +0 -17
- data/lib/neo4j-embedded/embedded_label.rb +0 -88
- data/lib/neo4j-embedded/embedded_node.rb +0 -206
- data/lib/neo4j-embedded/embedded_relationship.rb +0 -77
- data/lib/neo4j-embedded/embedded_session.rb +0 -203
- data/lib/neo4j-embedded/embedded_transaction.rb +0 -30
- data/lib/neo4j-embedded/label.rb +0 -66
- data/lib/neo4j-embedded/property.rb +0 -106
- data/lib/neo4j-embedded/to_java.rb +0 -44
- data/lib/neo4j-server.rb +0 -12
- data/lib/neo4j-server/cypher_label.rb +0 -35
- data/lib/neo4j-server/cypher_node.rb +0 -221
- data/lib/neo4j-server/cypher_relationship.rb +0 -142
- data/lib/neo4j-server/cypher_response.rb +0 -248
- data/lib/neo4j-server/cypher_session.rb +0 -263
- data/lib/neo4j-server/cypher_transaction.rb +0 -100
- data/lib/neo4j-server/label.rb +0 -40
- data/lib/neo4j-server/resource.rb +0 -57
- data/lib/neo4j/entity_equality.rb +0 -8
- data/lib/neo4j/entity_marshal.rb +0 -20
- data/lib/neo4j/label.rb +0 -90
- data/lib/neo4j/node.rb +0 -216
- data/lib/neo4j/property_container.rb +0 -17
- data/lib/neo4j/property_validator.rb +0 -22
- data/lib/neo4j/relationship.rb +0 -161
- data/lib/neo4j/session.rb +0 -222
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 95c3a0a71e52de4f4ef573cc36ff3d206a1fcd3ba443a84890e3c42c6ca6cc39
|
4
|
+
data.tar.gz: '05885ecf4289f9fae5d67234f82324c24289e4ab0a1fff8ffc6569810e71a496'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab2abc2fa87addc1ef0b2ebb0e3e67886d773d0542bf3a2850f17adc39c27e9faae92a0f528b8e8785de28bced39cbd19d5a264ee27f1584f1f34ccd21383049
|
7
|
+
data.tar.gz: 686135288df838098db8b40ede27157bc02d335eef6b041b18ee4c7f24a2f0f28bdc98f1d5ada1a15e864e9e24d7caf1acb8aae2003b44696041b9c9ad44d8c9
|
data/README.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
# Neo4j-core
|
1
|
+
# Neo4j-core
|
2
|
+
|
3
|
+
[![Actively Maintained](https://img.shields.io/badge/Maintenance%20Level-Actively%20Maintained-green.svg)](https://gist.github.com/cheerfulstoic/d107229326a01ff0f333a1d3476e068d)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/neo4jrb/neo4j-core.svg)](https://codeclimate.com/github/neo4jrb/neo4j-core)
|
5
|
+
[![Build Status](https://travis-ci.org/neo4jrb/neo4j-core.svg)](https://travis-ci.org/neo4jrb/neo4j-core)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/neo4jrb/neo4j-core/badge.svg?branch=master)](https://coveralls.io/r/neo4jrb/neo4j-core?branch=master)
|
7
|
+
[![PullReview stats](https://www.pullreview.com/github/neo4jrb/neo4j-core/badges/master.svg?)](https://www.pullreview.com/github/neo4jrb/neo4j-core/reviews/master)
|
2
8
|
|
3
9
|
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
10
|
It can be used standalone without the neo4j gem.
|
@@ -9,15 +15,20 @@ It can be used standalone without the neo4j gem.
|
|
9
15
|
|
10
16
|
To make a basic connection to Neo4j to execute Cypher queries, first choose an adaptor. Adaptors for HTTP, Bolt, and Embedded mode (jRuby only) are available. You can create an adaptor like:
|
11
17
|
|
12
|
-
|
18
|
+
require 'neo4j/core/cypher_session/adaptors/http'
|
19
|
+
http_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://neo4j:pass@localhost:7474', options)
|
13
20
|
|
14
21
|
# or
|
15
22
|
|
16
|
-
|
23
|
+
require 'neo4j/core/cypher_session/adaptors/bolt'
|
24
|
+
bolt_adaptor = Neo4j::Core::CypherSession::Adaptors::Bolt.new('bolt://neo4j:pass@localhost:7687', options)
|
17
25
|
|
18
26
|
# or
|
19
27
|
|
20
|
-
|
28
|
+
require 'neo4j/core/cypher_session/adaptors/embedded'
|
29
|
+
neo4j_adaptor = Neo4j::Core::CypherSession::Adaptors::Embedded.new('/file/path/to/graph.db', options)
|
30
|
+
|
31
|
+
The options are specific to each adaptor. See below for details.
|
21
32
|
|
22
33
|
Once you have an adaptor you can create a session like so:
|
23
34
|
|
@@ -55,15 +66,67 @@ When doing batched queries, there is also a shortcut for getting a new `Neo4j::C
|
|
55
66
|
|
56
67
|
results[0] # result
|
57
68
|
|
69
|
+
### Adaptor Options
|
70
|
+
|
71
|
+
As mentioned above, each of the adaptors take different sets of options. They are enumerated below:
|
72
|
+
|
73
|
+
#### Shared options
|
74
|
+
|
75
|
+
All adaptors take `wrap_level` as an option. This can be used to control how nodes, relationships, and path data is returned:
|
76
|
+
|
77
|
+
* `wrap_level: :none` will return Ruby hashes
|
78
|
+
* `wrap_level: :core_entity` will return objects from the `neo4j-core` gem (`Neo4j::Core::Node`, `Neo4j::Core::Relationship`, and `Neo4j::Core::Path`
|
79
|
+
* `wrap_level: :prop` allows you to define Ruby Procs to do your own wrapping. This is how the `neo4j` gem provides `ActiveNode` and `ActiveRel` objects (see the [`node_wrapper.rb`](https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/node_wrapper.rb) and [`rel_wrapper.rb`](https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_rel/rel_wrapper.rb) files for examples on how this works
|
80
|
+
|
81
|
+
All adaptors will also take either a `logger` option with a Ruby logger to define where it will log to.
|
82
|
+
|
83
|
+
All adaptors will also take the `skip_instrumentation` option to skip logging of queries.
|
84
|
+
|
85
|
+
All adaptors will also take the `verbose_query_logs` option which can be `true` or `false` (`false` being the default). This will change the logging to output the source line of code which caused a query to be executed (note that the `skip_instrumentation` should not be set for logging to be produced).
|
86
|
+
|
87
|
+
#### Bolt
|
88
|
+
|
89
|
+
The Bolt adaptor takes `connect_timeout`, `read_timeout`, and `write_timeout` options which define appropriate timeouts. The `connect_timeout` is 10 seconds and the `read_timeout` and `write_timeout` are -1 (no timeout). This is to cause the underlying `net_tcp_client` gem to operate in blocking mode (as opposed to non-blocking mode). When using non-blocking mode problems were found and since the official Neo4j drivers in other languages use blocking mode, this is what this gem uses by default. This issue could potentially be a bug in the handling of the `EAGAIN` signal, but it was not investigated further. Set the read/write timeouts at your own risk.
|
90
|
+
|
91
|
+
The Bolt adaptor also takes an `ssl` option which also corresponds to `net_tcp_client`'s `ssl` option (which, in turn, corresponds to Ruby's `OpenSSL::SSL::SSLContext`). By default SSL is used. For most cloud providers that use public certificate authorities this open generally won't be needed. If you've setup Neo4j yourself you will need to provide the certificate like so:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
cert_store = OpenSSL::X509::Store.new
|
95
|
+
cert_store.add_file('/the/path/to/your/neo4j.cert')
|
96
|
+
ssl: {cert_store: cert_store}}
|
97
|
+
bolt_adaptor = Neo4j::Core::CypherSession::Adaptors::Bolt.new('bolt://neo4j:pass@localhost:7687', ssl: {cert_store: cert_store})
|
98
|
+
```
|
99
|
+
|
100
|
+
You can also turn SSL off by simply specifying `ssl: false`
|
101
|
+
|
102
|
+
#### HTTP
|
103
|
+
|
104
|
+
Since the HTTP adaptor uses the `faraday` gem under the covers, it takes a `faraday_configurator` option. This allows you to pass in a `Proc` which works just like a Faraday setup block:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
faraday_configurator: proc do |faraday|
|
108
|
+
# The default configurator uses typhoeus so if you override the configurator you must specify this
|
109
|
+
faraday.adapter :typhoeus
|
110
|
+
# Optionally you can instead specify another adaptor
|
111
|
+
# faraday.use Faraday::Adapter::NetHttpPersistent
|
112
|
+
|
113
|
+
# If you need to set options which would normally be the second argument of `Faraday.new`, you can do the following:
|
114
|
+
faraday.options[:open_timeout] = 5
|
115
|
+
faraday.options[:timeout] = 65
|
116
|
+
# faraday.options[:ssl] = { verify: true }
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
#### Embedded
|
121
|
+
|
122
|
+
The Embedded adaptor takes `properties_file` and `properties_map` options which are passed to `loadPropertiesFromFile` and `setConfig` on the `GraphDatabaseBuilder` class from the Neo4j Java API.
|
123
|
+
|
58
124
|
## Documentation
|
59
125
|
|
60
|
-
|
126
|
+
Our documentation on ReadTheDocs covers both the `neo4j` and `neo4j-core` gems:
|
61
127
|
|
62
128
|
* http://neo4jrb.readthedocs.org/en/stable/
|
63
129
|
|
64
|
-
### 2.x Documentation
|
65
|
-
|
66
|
-
https://github.com/neo4jrb/neo4j-core/tree/v2.x
|
67
130
|
|
68
131
|
## Support
|
69
132
|
|
data/lib/neo4j-core.rb
CHANGED
@@ -1,49 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
4
|
-
require 'forwardable'
|
5
|
-
require 'fileutils'
|
6
|
-
|
7
|
-
require 'neo4j-core/version'
|
8
|
-
require 'neo4j/property_validator'
|
9
|
-
require 'neo4j/property_container'
|
10
|
-
require 'neo4j/entity_marshal'
|
11
|
-
require 'neo4j-core/active_entity'
|
12
|
-
require 'neo4j-core/helpers'
|
13
|
-
require 'neo4j-core/query_find_in_batches'
|
14
|
-
require 'neo4j-core/query'
|
15
|
-
|
16
|
-
require 'neo4j/entity_equality'
|
17
|
-
require 'neo4j/node'
|
18
|
-
require 'neo4j/label'
|
19
|
-
require 'neo4j/session'
|
20
|
-
require 'neo4j/ansi'
|
21
|
-
|
22
|
-
require 'neo4j/relationship'
|
23
|
-
require 'neo4j/transaction'
|
24
|
-
|
25
|
-
require 'rake'
|
26
|
-
load 'neo4j/core/rake_tasks_deprecation.rake'
|
27
|
-
|
28
|
-
require 'logger'
|
29
|
-
|
30
|
-
module Neo4j
|
31
|
-
module Core
|
32
|
-
ORIGINAL_FORMATTER = ::Logger::Formatter.new
|
33
|
-
|
34
|
-
def self.logger(stream = STDOUT)
|
35
|
-
@logger ||= Logger.new(stream).tap do |logger|
|
36
|
-
logger.formatter = method(:formatter)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.formatter(severity, datetime, progname, msg)
|
41
|
-
output = ''
|
42
|
-
if Thread.current != Thread.main
|
43
|
-
output += "#{ANSI::YELLOW}Thread: #{Thread.current.object_id}: #{ANSI::CLEAR}"
|
44
|
-
end
|
45
|
-
output += msg
|
46
|
-
ORIGINAL_FORMATTER.call(severity, datetime, progname, output)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
1
|
+
# DO NOT ADD ANYTHING HERE
|
2
|
+
# lib/neo4j/core.rb should be the base for requiring essential files
|
3
|
+
require 'neo4j/core'
|
data/lib/neo4j/core.rb
ADDED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'neo4j/core/cypher_session'
|
2
2
|
require 'neo4j/core/instrumentable'
|
3
3
|
require 'neo4j/core/label'
|
4
|
-
require 'neo4j
|
4
|
+
require 'neo4j/core/version'
|
5
|
+
require 'neo4j/core/logging'
|
6
|
+
require 'neo4j/ansi'
|
5
7
|
|
6
8
|
module Neo4j
|
7
9
|
module Core
|
@@ -22,7 +24,6 @@ ERROR
|
|
22
24
|
super(msg)
|
23
25
|
end
|
24
26
|
|
25
|
-
|
26
27
|
def self.new_from(code, message, stack_trace = nil)
|
27
28
|
error_class_from(code).new(code, message, stack_trace)
|
28
29
|
end
|
@@ -67,6 +68,7 @@ ERROR
|
|
67
68
|
end
|
68
69
|
|
69
70
|
attr_accessor :wrap_level
|
71
|
+
attr_reader :options
|
70
72
|
|
71
73
|
Query = Struct.new(:cypher, :parameters, :pretty_cypher, :context)
|
72
74
|
|
@@ -162,31 +164,29 @@ ERROR
|
|
162
164
|
end
|
163
165
|
|
164
166
|
def setup_queries!(queries, transaction, options = {})
|
165
|
-
|
166
|
-
fail "Invalid transaction object: #{transaction.inspect}" if !transaction.is_a?(self.class.transaction_class)
|
167
|
+
validate_connection!(transaction)
|
167
168
|
|
168
|
-
|
169
|
-
|
169
|
+
return if options[:skip_instrumentation]
|
170
|
+
queries.each do |query|
|
171
|
+
self.class.instrument_query(query, self) {}
|
172
|
+
end
|
170
173
|
end
|
171
174
|
|
172
175
|
EMPTY = ''
|
173
176
|
NEWLINE_W_SPACES = "\n "
|
174
177
|
|
175
|
-
instrument(:query, 'neo4j.core.cypher_query', %w[query]) do |_, _start, _finish, _id, payload|
|
178
|
+
instrument(:query, 'neo4j.core.cypher_query', %w[query adaptor]) do |_, _start, _finish, _id, payload|
|
176
179
|
query = payload[:query]
|
177
180
|
params_string = (query.parameters && !query.parameters.empty? ? "| #{query.parameters.inspect}" : EMPTY)
|
178
181
|
cypher = query.pretty_cypher ? (NEWLINE_W_SPACES if query.pretty_cypher.include?("\n")).to_s + query.pretty_cypher.gsub(/\n/, NEWLINE_W_SPACES) : query.cypher
|
179
182
|
|
180
|
-
|
183
|
+
source_line, line_number = Logging.first_external_path_and_line(caller_locations)
|
184
|
+
|
185
|
+
" #{ANSI::CYAN}#{query.context || 'CYPHER'}#{ANSI::CLEAR} #{cypher} #{params_string}" +
|
186
|
+
("\n ↳ #{source_line}:#{line_number}" if payload[:adaptor].options[:verbose_query_logs] && source_line).to_s
|
181
187
|
end
|
182
188
|
|
183
189
|
class << self
|
184
|
-
def instrument_queries(queries)
|
185
|
-
queries.each do |query|
|
186
|
-
instrument_query(query) {}
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
190
|
def transaction_class
|
191
191
|
fail '.transaction_class method not implemented on adaptor!'
|
192
192
|
end
|
@@ -202,7 +202,7 @@ ERROR
|
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
205
|
-
def
|
205
|
+
def validate_connection!(transaction)
|
206
206
|
fail 'Query attempted without a connection' if !connected?
|
207
207
|
fail "Invalid transaction object: #{transaction}" if !transaction.is_a?(self.class.transaction_class)
|
208
208
|
end
|
@@ -3,10 +3,9 @@ require 'neo4j/core/cypher_session/adaptors/has_uri'
|
|
3
3
|
require 'neo4j/core/cypher_session/adaptors/bolt/pack_stream'
|
4
4
|
require 'neo4j/core/cypher_session/adaptors/bolt/chunk_writer_io'
|
5
5
|
require 'neo4j/core/cypher_session/responses/bolt'
|
6
|
-
require '
|
7
|
-
require 'socket'
|
6
|
+
require 'net/tcp_client'
|
8
7
|
|
9
|
-
# TODO: Work with `Query` objects
|
8
|
+
# TODO: Work with `Query` objects?
|
10
9
|
module Neo4j
|
11
10
|
module Core
|
12
11
|
class CypherSession
|
@@ -24,6 +23,10 @@ module Neo4j
|
|
24
23
|
def initialize(url, options = {})
|
25
24
|
self.url = url
|
26
25
|
@options = options
|
26
|
+
@net_tcp_client_options = {read_timeout: options.fetch(:read_timeout, -1),
|
27
|
+
write_timeout: options.fetch(:write_timeout, -1),
|
28
|
+
connect_timeout: options.fetch(:connect_timeout, 10),
|
29
|
+
ssl: options.fetch(:ssl, {})}
|
27
30
|
|
28
31
|
open_socket
|
29
32
|
end
|
@@ -43,13 +46,7 @@ module Neo4j
|
|
43
46
|
def query_set(transaction, queries, options = {})
|
44
47
|
setup_queries!(queries, transaction, skip_instrumentation: options[:skip_instrumentation])
|
45
48
|
|
46
|
-
|
47
|
-
debug_remaining_buffer
|
48
|
-
fail "Making query, but expected there to be no buffer remaining!\n"\
|
49
|
-
"Queries: #{queries.map(&:cypher)}"
|
50
|
-
end
|
51
|
-
|
52
|
-
self.class.instrument_request do
|
49
|
+
self.class.instrument_request(self) do
|
53
50
|
send_query_jobs(queries)
|
54
51
|
|
55
52
|
build_response(queries, options[:wrap_level] || @options[:wrap_level])
|
@@ -64,7 +61,7 @@ module Neo4j
|
|
64
61
|
end
|
65
62
|
|
66
63
|
def connected?
|
67
|
-
!!@
|
64
|
+
!!@tcp_client && !@tcp_client.closed?
|
68
65
|
end
|
69
66
|
|
70
67
|
def indexes(session)
|
@@ -90,10 +87,16 @@ module Neo4j
|
|
90
87
|
Neo4j::Core::CypherSession::Transactions::Bolt
|
91
88
|
end
|
92
89
|
|
93
|
-
instrument(:request, 'neo4j.core.bolt.request', %w[
|
90
|
+
instrument(:request, 'neo4j.core.bolt.request', %w[adaptor body]) do |_, start, finish, _id, payload|
|
94
91
|
ms = (finish - start) * 1000
|
92
|
+
adaptor = payload[:adaptor]
|
95
93
|
|
96
|
-
|
94
|
+
type = adaptor.ssl? ? '+TLS' : ' UNSECURE'
|
95
|
+
" #{ANSI::BLUE}BOLT#{type}:#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR} #{adaptor.url_without_password}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def ssl?
|
99
|
+
@tcp_client.socket.is_a?(OpenSSL::SSL::SSLSocket)
|
97
100
|
end
|
98
101
|
|
99
102
|
private
|
@@ -117,17 +120,6 @@ module Neo4j
|
|
117
120
|
fail CypherError.new_from(error_data['code'], error_data['message'])
|
118
121
|
end
|
119
122
|
|
120
|
-
def debug_remaining_buffer
|
121
|
-
logger.debug 'Remaining buffer:'
|
122
|
-
|
123
|
-
i = 0
|
124
|
-
while @socket.ready?
|
125
|
-
i += 1
|
126
|
-
logger.debug "Message set #{i}:"
|
127
|
-
flush_messages
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
123
|
def send_query_jobs(queries)
|
132
124
|
send_job do |job|
|
133
125
|
queries.each do |query|
|
@@ -141,8 +133,12 @@ module Neo4j
|
|
141
133
|
Job.new(self)
|
142
134
|
end
|
143
135
|
|
136
|
+
def secure_connection?
|
137
|
+
@is_secure_socket ||= @options.key?(:ssl)
|
138
|
+
end
|
139
|
+
|
144
140
|
def open_socket
|
145
|
-
@
|
141
|
+
@tcp_client = Net::TCPClient.new(@net_tcp_client_options.merge(buffered: false, server: "#{host}:#{port}"))
|
146
142
|
rescue Errno::ECONNREFUSED => e
|
147
143
|
raise Neo4j::Core::CypherSession::ConnectionFailedError, e.message
|
148
144
|
end
|
@@ -156,13 +152,12 @@ module Neo4j
|
|
156
152
|
agreed_version = recvmsg(4).unpack('l>*')[0]
|
157
153
|
|
158
154
|
if agreed_version.zero?
|
159
|
-
@
|
160
|
-
@socket.close
|
155
|
+
@tcp_client.close
|
161
156
|
|
162
157
|
fail "Couldn't agree on a version (Sent versions #{SUPPORTED_VERSIONS.inspect})"
|
163
158
|
end
|
164
159
|
|
165
|
-
logger.debug "Agreed to version: #{agreed_version}"
|
160
|
+
logger.debug { "Agreed to version: #{agreed_version}" }
|
166
161
|
end
|
167
162
|
|
168
163
|
def init
|
@@ -181,42 +176,42 @@ module Neo4j
|
|
181
176
|
end
|
182
177
|
end
|
183
178
|
|
179
|
+
# Don't need to calculate these every time. Cache in memory
|
180
|
+
BYTE_STRINGS = (0..255).map { |byte| byte.to_s(16).rjust(2, '0') }
|
181
|
+
|
184
182
|
STREAM_INSPECTOR = lambda do |stream|
|
185
|
-
stream.bytes.map { |byte| byte
|
183
|
+
stream.bytes.map { |byte| BYTE_STRINGS[byte] }.join(':')
|
186
184
|
end
|
187
185
|
|
188
186
|
def sendmsg(message)
|
189
187
|
log_message :C, message
|
190
|
-
|
191
|
-
@socket.send(message, 0)
|
188
|
+
@tcp_client.write(message)
|
192
189
|
end
|
193
190
|
|
194
|
-
def recvmsg(size
|
195
|
-
|
196
|
-
|
197
|
-
log_message :S, result
|
198
|
-
end
|
191
|
+
def recvmsg(size)
|
192
|
+
@tcp_client.read(size) do |result|
|
193
|
+
log_message :S, result
|
199
194
|
end
|
200
|
-
rescue Timeout::Error
|
201
|
-
raise "Timed out waiting for #{size} bytes from Neo4j (after #{timeout} seconds)"
|
202
195
|
end
|
203
196
|
|
204
197
|
def flush_messages
|
205
198
|
if structures = flush_response
|
206
199
|
structures.map do |structure|
|
207
200
|
Message.new(structure.signature, *structure.list).tap do |message|
|
208
|
-
log_message :S, message.type, message.args.join(' ')
|
201
|
+
log_message :S, message.type, message.args.join(' ') if logger.debug?
|
209
202
|
end
|
210
203
|
end
|
211
204
|
end
|
212
205
|
end
|
213
206
|
|
214
207
|
def log_message(side, *args)
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
208
|
+
logger.debug do
|
209
|
+
if args.size == 1
|
210
|
+
"#{side}: #{STREAM_INSPECTOR.call(args[0])}"
|
211
|
+
else
|
212
|
+
type, message = args
|
213
|
+
"#{side}: #{ANSI::CYAN}#{type.to_s.upcase}#{ANSI::CLEAR} #{message}"
|
214
|
+
end
|
220
215
|
end
|
221
216
|
end
|
222
217
|
|
@@ -234,10 +229,6 @@ module Neo4j
|
|
234
229
|
[].tap { |r| while arg = unpacker.unpack_value!; r << arg; end }
|
235
230
|
end
|
236
231
|
|
237
|
-
def timeout_option
|
238
|
-
@options.fetch(:timeout) { 10 }
|
239
|
-
end
|
240
|
-
|
241
232
|
# Represents messages sent to or received from the server
|
242
233
|
class Message
|
243
234
|
TYPE_CODES = {
|