neospace 0.0.1 → 1.7.0
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 +4 -4
- data/LICENSE.txt +21 -0
- data/README.md +88 -0
- data/ffi/bolt/address.rb +11 -0
- data/ffi/bolt/address_resolver.rb +12 -0
- data/ffi/bolt/address_set.rb +9 -0
- data/ffi/bolt/auth.rb +10 -0
- data/ffi/bolt/auto_releasable.rb +22 -0
- data/ffi/bolt/boolean.rb +9 -0
- data/ffi/bolt/bytes.rb +10 -0
- data/ffi/bolt/config.rb +45 -0
- data/ffi/bolt/connection.rb +44 -0
- data/ffi/bolt/connector.rb +17 -0
- data/ffi/bolt/dictionary.rb +15 -0
- data/ffi/bolt/error.rb +74 -0
- data/ffi/bolt/float.rb +9 -0
- data/ffi/bolt/integer.rb +9 -0
- data/ffi/bolt/library.rb +12 -0
- data/ffi/bolt/lifecycle.rb +9 -0
- data/ffi/bolt/list.rb +10 -0
- data/ffi/bolt/log.rb +16 -0
- data/ffi/bolt/socket_options.rb +14 -0
- data/ffi/bolt/status.rb +25 -0
- data/ffi/bolt/string.rb +9 -0
- data/ffi/bolt/structure.rb +10 -0
- data/ffi/bolt/value.rb +35 -0
- data/ffi/neo4j/driver.rb +60 -0
- data/ffi/neo4j/driver/access_mode.rb +10 -0
- data/ffi/neo4j/driver/auth_tokens.rb +18 -0
- data/ffi/neo4j/driver/config.rb +40 -0
- data/ffi/neo4j/driver/graph_database.rb +52 -0
- data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +19 -0
- data/ffi/neo4j/driver/internal/async/direct_connection.rb +106 -0
- data/ffi/neo4j/driver/internal/bolt_server_address.rb +18 -0
- data/ffi/neo4j/driver/internal/bookmarks_holder.rb +30 -0
- data/ffi/neo4j/driver/internal/direct_connection_provider.rb +28 -0
- data/ffi/neo4j/driver/internal/driver_factory.rb +125 -0
- data/ffi/neo4j/driver/internal/error_handling.rb +108 -0
- data/ffi/neo4j/driver/internal/explicit_transaction.rb +146 -0
- data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +105 -0
- data/ffi/neo4j/driver/internal/handlers/response_handler.rb +49 -0
- data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +32 -0
- data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +32 -0
- data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +23 -0
- data/ffi/neo4j/driver/internal/internal_driver.rb +45 -0
- data/ffi/neo4j/driver/internal/internal_logger.rb +32 -0
- data/ffi/neo4j/driver/internal/internal_record.rb +26 -0
- data/ffi/neo4j/driver/internal/internal_resolver.rb +31 -0
- data/ffi/neo4j/driver/internal/internal_statement_result.rb +52 -0
- data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +24 -0
- data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +59 -0
- data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +16 -0
- data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +63 -0
- data/ffi/neo4j/driver/internal/network_session.rb +129 -0
- data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +80 -0
- data/ffi/neo4j/driver/internal/session_factory_impl.rb +28 -0
- data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +67 -0
- data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +19 -0
- data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +23 -0
- data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +15 -0
- data/ffi/neo4j/driver/internal/value/base_time_value.rb +22 -0
- data/ffi/neo4j/driver/internal/value/date_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/duration_value.rb +27 -0
- data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/local_time_value.rb +19 -0
- data/ffi/neo4j/driver/internal/value/node_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/offset_time_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/path_value.rb +41 -0
- data/ffi/neo4j/driver/internal/value/point2_d_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/point3_d_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/relationship_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/structure_value.rb +42 -0
- data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +28 -0
- data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/value_adapter.rb +99 -0
- data/ffi/neo4j/driver/net/server_address.rb +13 -0
- data/ffi/neo4j/driver/statement.rb +15 -0
- data/ffi/neo4j/driver/summary/statement_type.rb +14 -0
- data/ffi/neo4j/driver/types/entity.rb +21 -0
- data/ffi/neo4j/driver/types/node.rb +16 -0
- data/ffi/neo4j/driver/types/path.rb +35 -0
- data/ffi/neo4j/driver/types/relationship.rb +19 -0
- data/lib/loader.rb +18 -0
- data/lib/neo4j/driver/auto_closable.rb +32 -0
- data/lib/neo4j/driver/exceptions/authentication_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/client_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/database_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/neo4j_exception.rb +23 -0
- data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/security_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/session_expired_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/transient_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +10 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +46 -0
- data/lib/neo4j/driver/internal/ruby_signature.rb +18 -0
- data/lib/neo4j/driver/internal/validator.rb +28 -0
- data/lib/neo4j/driver/types/bytes.rb +10 -0
- data/lib/neo4j/driver/types/local_date_time.rb +20 -0
- data/lib/neo4j/driver/types/local_time.rb +19 -0
- data/lib/neo4j/driver/types/offset_time.rb +19 -0
- data/lib/neo4j/driver/types/point.rb +39 -0
- data/lib/neo4j/driver/types/time.rb +43 -0
- data/lib/neo4j/driver/version.rb +7 -0
- data/lib/neo4j_ruby_driver.rb +20 -0
- metadata +314 -12
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Messaging
|
|
7
|
+
module V1
|
|
8
|
+
class BoltProtocolV1
|
|
9
|
+
VERSION = 1
|
|
10
|
+
INSTANCE = new
|
|
11
|
+
|
|
12
|
+
METADATA_EXTRACTOR = Util::MetadataExtractor.new('result_available_after', 'result_consumed_after')
|
|
13
|
+
|
|
14
|
+
def run_in_auto_commit_transaction(connection, statement, bookmarks_holder, config)
|
|
15
|
+
# bookmarks are ignored for auto-commit transactions in this version of the protocol
|
|
16
|
+
|
|
17
|
+
self.class.tx_config_not_supported if config&.present?
|
|
18
|
+
|
|
19
|
+
self.class.run_statement(connection, statement, nil)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run_in_explicit_transaction(connection, statement, tx)
|
|
23
|
+
self.class.run_statement(connection, statement, tx)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
def run_statement(connection, statement, tx)
|
|
28
|
+
query = statement.text
|
|
29
|
+
params = statement.parameters
|
|
30
|
+
|
|
31
|
+
run_handler = Handlers::RunResponseHandler.new(METADATA_EXTRACTOR)
|
|
32
|
+
pull_all_handler = new_pull_all_handler(statement, run_handler, connection, tx)
|
|
33
|
+
|
|
34
|
+
connection.write_and_flush(query, params, run_handler, pull_all_handler)
|
|
35
|
+
InternalStatementResult.new(run_handler, pull_all_handler)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def new_pull_all_handler(statement, run_handler, connection, tx)
|
|
39
|
+
if tx
|
|
40
|
+
Handlers::TransactionPullAllResponseHandler.new(statement, run_handler, connection, tx,
|
|
41
|
+
METADATA_EXTRACTOR)
|
|
42
|
+
else
|
|
43
|
+
Handlers::SessionPullAllResponseHandler.new(statement, run_handler, connection,
|
|
44
|
+
BookmarksHolder::NO_OP, METADATA_EXTRACTOR)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def tx_config_not_supported
|
|
49
|
+
raise ClientException,
|
|
50
|
+
'Driver is connected to the database that does not support transaction configuration. ' \
|
|
51
|
+
'Please upgrade to neo4j 3.5.0 or later in order to use this functionality'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Messaging
|
|
7
|
+
module V3
|
|
8
|
+
class BoltProtocolV3
|
|
9
|
+
VERSION = 3
|
|
10
|
+
INSTANCE = new
|
|
11
|
+
METADATA_EXTRACTOR = Util::MetadataExtractor.new('t_first', 't_last')
|
|
12
|
+
|
|
13
|
+
def run_in_auto_commit_transaction(connection, statement, bookmarks_holder, config)
|
|
14
|
+
self.class.run_statement(connection, statement, bookmarks_holder, nil, config)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run_in_explicit_transaction(connection, statement, tx)
|
|
18
|
+
self.class.run_statement(connection, statement, BookmarksHolder::NO_OP, tx, nil)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def begin_transaction(connection, bookmarks, config)
|
|
22
|
+
begin_handler = Handlers::ResponseHandler.new(connection)
|
|
23
|
+
connection.begin(bookmarks, config, begin_handler)
|
|
24
|
+
connection.flush if bookmarks.present?
|
|
25
|
+
begin_handler
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def commit_transaction(connection)
|
|
29
|
+
Handlers::ResponseHandler.new(connection).tap(&connection.method(:commit))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rollback_transaction(connection)
|
|
33
|
+
Handlers::ResponseHandler.new(connection).tap(&connection.method(:rollback))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
def run_statement(connection, statement, boomarks_holder, tx, config)
|
|
38
|
+
query = statement.text
|
|
39
|
+
params = statement.parameters
|
|
40
|
+
|
|
41
|
+
run_handler = Handlers::RunResponseHandler.new(connection, METADATA_EXTRACTOR)
|
|
42
|
+
pull_all_handler = new_pull_all_handler(statement, run_handler, connection, boomarks_holder, tx)
|
|
43
|
+
|
|
44
|
+
connection.write_and_flush(query, params, boomarks_holder, config, run_handler, pull_all_handler)
|
|
45
|
+
InternalStatementResult.new(run_handler, pull_all_handler)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def new_pull_all_handler(statement, run_handler, connection, bookmarks_holder, tx)
|
|
49
|
+
if tx
|
|
50
|
+
Handlers::TransactionPullAllResponseHandler.new(statement, run_handler, connection, tx,
|
|
51
|
+
METADATA_EXTRACTOR)
|
|
52
|
+
else
|
|
53
|
+
Handlers::SessionPullAllResponseHandler.new(statement, run_handler, connection, bookmarks_holder,
|
|
54
|
+
METADATA_EXTRACTOR)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
class NetworkSession
|
|
7
|
+
include BookmarksHolder
|
|
8
|
+
include ErrorHandling
|
|
9
|
+
extend AutoClosable
|
|
10
|
+
|
|
11
|
+
auto_closable :begin_transaction
|
|
12
|
+
|
|
13
|
+
def initialize(connection_provider, mode, retry_logic = nil, logging = nil)
|
|
14
|
+
super()
|
|
15
|
+
@open = Concurrent::AtomicBoolean.new(true)
|
|
16
|
+
@connection_provider = connection_provider
|
|
17
|
+
@mode = mode
|
|
18
|
+
@retry_logic = retry_logic
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def run(statement, parameters = {}, config = {})
|
|
22
|
+
ensure_session_is_open
|
|
23
|
+
ensure_no_open_tx_before_running_query
|
|
24
|
+
acquire_connection(@mode)
|
|
25
|
+
@result = @connection.protocol.run_in_auto_commit_transaction(
|
|
26
|
+
@connection, Statement.new(statement, parameters), self, config
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def read_transaction(**config, &block)
|
|
31
|
+
transaction(Neo4j::Driver::AccessMode::READ, config, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def write_transaction(**config, &block)
|
|
35
|
+
transaction(Neo4j::Driver::AccessMode::WRITE, config, &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def close
|
|
39
|
+
return unless @open.make_false
|
|
40
|
+
begin
|
|
41
|
+
@result&.finalize
|
|
42
|
+
@result&.failure
|
|
43
|
+
ensure
|
|
44
|
+
close_transaction_and_release_connection
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def release_connection
|
|
49
|
+
@connection&.release
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def begin_transaction(**config)
|
|
53
|
+
private_begin_transaction(@mode, config)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def last_bookmark
|
|
57
|
+
bookmarks&.max
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def open?
|
|
61
|
+
@open.true?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def private_begin_transaction(mode, config)
|
|
67
|
+
ensure_session_is_open
|
|
68
|
+
ensure_no_open_tx_before_starting_tx
|
|
69
|
+
acquire_connection(mode)
|
|
70
|
+
@transaction = ExplicitTransaction.new(@connection, self).begin(bookmarks, config)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def transaction(mode, config)
|
|
74
|
+
@retry_logic.retry do
|
|
75
|
+
tx = private_begin_transaction(mode, config)
|
|
76
|
+
result = yield tx
|
|
77
|
+
tx.success
|
|
78
|
+
result
|
|
79
|
+
rescue StandardError => e
|
|
80
|
+
tx&.failure
|
|
81
|
+
raise e
|
|
82
|
+
ensure
|
|
83
|
+
tx&.close
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def acquire_connection(mode)
|
|
88
|
+
# make sure previous result is fully consumed and connection is released back to the pool
|
|
89
|
+
@result&.failure
|
|
90
|
+
|
|
91
|
+
# there is no unconsumed error, so one of the following is true:
|
|
92
|
+
# 1) this is first time connection is acquired in this session
|
|
93
|
+
# 2) previous result has been successful and is fully consumed
|
|
94
|
+
# 3) previous result failed and error has been consumed
|
|
95
|
+
|
|
96
|
+
raise Exceptions::IllegalStateException, 'Existing open connection detected' if @connection&.open?
|
|
97
|
+
@connection = @connection_provider.acquire_connection(mode)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def close_transaction_and_release_connection
|
|
101
|
+
@transaction&.close
|
|
102
|
+
ensure
|
|
103
|
+
@transaction = nil
|
|
104
|
+
release_connection
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def ensure_session_is_open
|
|
108
|
+
return if open?
|
|
109
|
+
raise Exceptions::ClientException,
|
|
110
|
+
'No more interaction with this session are allowed as the current session is already closed.'
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def ensure_no_open_tx_before_running_query
|
|
114
|
+
ensure_no_open_tx('Statements cannot be run directly on a session with an open transaction; ' \
|
|
115
|
+
'either run from within the transaction or use a different session.')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def ensure_no_open_tx_before_starting_tx
|
|
119
|
+
ensure_no_open_tx('You cannot begin a transaction on a session with an open transaction; ' \
|
|
120
|
+
'either run from within the transaction or use a different session.')
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def ensure_no_open_tx(error_message)
|
|
124
|
+
raise Exceptions::ClientException, error_message if @transaction&.open?
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Retry
|
|
7
|
+
class ExponentialBackoffRetryLogic
|
|
8
|
+
DEFAULT_MAX_RETRY_TIME = 30.seconds
|
|
9
|
+
INITIAL_RETRY_DELAY = 1.second
|
|
10
|
+
RETRY_DELAY_MULTIPLIER = 2.0
|
|
11
|
+
RETRY_DELAY_JITTER_FACTOR = 0.2
|
|
12
|
+
|
|
13
|
+
def initialize(max_retry_time = nil, logger = nil)
|
|
14
|
+
@max_retry_time = max_retry_time || DEFAULT_MAX_RETRY_TIME
|
|
15
|
+
@log = logger
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def retry
|
|
19
|
+
next_delay = INITIAL_RETRY_DELAY
|
|
20
|
+
start_time = nil
|
|
21
|
+
errors = nil
|
|
22
|
+
begin
|
|
23
|
+
yield
|
|
24
|
+
rescue Exceptions::Neo4jException => error
|
|
25
|
+
if can_retry_on?(error)
|
|
26
|
+
curr_time = current_time
|
|
27
|
+
start_time ||= curr_time
|
|
28
|
+
elapsed_time = curr_time - start_time
|
|
29
|
+
if elapsed_time < @max_retry_time
|
|
30
|
+
delay_with_jitter = compute_delay_with_jitter(next_delay)
|
|
31
|
+
@log&.warn { "Transaction failed and will be retried in #{delay_with_jitter}ms\n#{error}" }
|
|
32
|
+
sleep(delay_with_jitter)
|
|
33
|
+
next_delay *= RETRY_DELAY_MULTIPLIER
|
|
34
|
+
(errors ||= []) << error
|
|
35
|
+
retry
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
add_suppressed(error, errors)
|
|
39
|
+
raise error
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def can_retry_on?(error)
|
|
46
|
+
error.is_a?(Exceptions::SessionExpiredException) ||
|
|
47
|
+
error.is_a?(Exceptions::ServiceUnavailableException) ||
|
|
48
|
+
transient_error?(error)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def transient_error?(error)
|
|
52
|
+
# Retries should not happen when transaction was explicitly terminated by the user.
|
|
53
|
+
# Termination of transaction might result in two different error codes depending on where it was
|
|
54
|
+
# terminated. These are really client errors but classification on the server is not entirely correct and
|
|
55
|
+
# they are classified as transient.
|
|
56
|
+
error.is_a?(Exceptions::TransientException) &&
|
|
57
|
+
!%w[Neo.TransientError.Transaction.Terminated Neo.TransientError.Transaction.LockClientStopped]
|
|
58
|
+
.include?(error.code)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def compute_delay_with_jitter(delay)
|
|
62
|
+
jitter = delay * RETRY_DELAY_JITTER_FACTOR
|
|
63
|
+
min = delay - jitter
|
|
64
|
+
max = delay + jitter
|
|
65
|
+
@rand ||= Random.new
|
|
66
|
+
@rand.rand(min..max)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def current_time
|
|
70
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def add_suppressed(error, suppressed_errors)
|
|
74
|
+
suppressed_errors&.reject(&error.method(:equal?))&.each(&error.method(:add_suppressed))
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
class SessionFactoryImpl
|
|
7
|
+
attr_reader :connection_provider
|
|
8
|
+
delegate :close, :verify_connectivity, to: :connection_provider
|
|
9
|
+
|
|
10
|
+
def initialize(connection_provider, retry_logic, config)
|
|
11
|
+
@connection_provider = connection_provider
|
|
12
|
+
@retry_logic = retry_logic
|
|
13
|
+
@config = config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def new_instance(mode, bookmarks)
|
|
17
|
+
create_session(connection_provider, @retry_logic, mode).tap { |session| session.bookmarks = bookmarks }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def create_session(connection_provider, retry_logic, mode, logging = nil)
|
|
23
|
+
NetworkSession.new(connection_provider, mode, retry_logic, logging)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Summary
|
|
7
|
+
class InternalResultSummary
|
|
8
|
+
attr_reader :server, :counters, :statement, :result_available_after, :result_consumed_after
|
|
9
|
+
delegate :notifications, :profile, to: :@metadata
|
|
10
|
+
|
|
11
|
+
def initialize(statement, result_available_after, bolt_connection)
|
|
12
|
+
@statement = statement
|
|
13
|
+
@result_available_after = result_available_after
|
|
14
|
+
@server = InternalServerInfo.new(bolt_connection)
|
|
15
|
+
@metadata = RecursiveOpenStruct.new(
|
|
16
|
+
underscore_keys(Value::ValueAdapter.to_ruby(Bolt::Connection.metadata(bolt_connection))),
|
|
17
|
+
recurse_over_arrays: true
|
|
18
|
+
)
|
|
19
|
+
@result_consumed_after = @metadata.result_consumed_after || @metadata.t_last
|
|
20
|
+
@counters = InternalSummaryCounters.new(@metadata.stats)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def notifications
|
|
24
|
+
@metadata.notifications || []
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def plan
|
|
28
|
+
@metadata.plan || profile
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias has_plan? plan
|
|
32
|
+
alias has_profile? profile
|
|
33
|
+
|
|
34
|
+
def method_missing(method)
|
|
35
|
+
@metadata.send(method)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def underscore_keys(arg)
|
|
41
|
+
case arg
|
|
42
|
+
when Array
|
|
43
|
+
arg.map(&method(:underscore_keys))
|
|
44
|
+
when Hash
|
|
45
|
+
arg.map { |key, value| [translate_key(key), underscore_keys(value)] }.to_h
|
|
46
|
+
else
|
|
47
|
+
arg
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def translate_key(key)
|
|
52
|
+
case key
|
|
53
|
+
when :type
|
|
54
|
+
:statement_type
|
|
55
|
+
when :args
|
|
56
|
+
:arguments
|
|
57
|
+
when :rows
|
|
58
|
+
:records
|
|
59
|
+
else
|
|
60
|
+
key.to_s.underscore.to_sym
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|