neo4j-ruby-driver 4.4.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/jruby/neo4j/driver/ext/async_converter.rb +55 -0
- data/jruby/neo4j/driver/ext/auth_tokens.rb +20 -0
- data/jruby/neo4j/driver/ext/bookmark.rb +15 -0
- data/jruby/neo4j/driver/ext/config_converter.rb +69 -0
- data/jruby/neo4j/driver/ext/exception_checkable.rb +34 -0
- data/jruby/neo4j/driver/ext/exception_mapper.rb +89 -0
- data/jruby/neo4j/driver/ext/graph_database.rb +29 -0
- data/jruby/neo4j/driver/ext/internal/async/internal_async_session.rb +23 -0
- data/jruby/neo4j/driver/ext/internal/cluster/routing_table_registry_impl.rb +15 -0
- data/jruby/neo4j/driver/ext/internal/cursor/disposable_async_result_cursor.rb +15 -0
- data/jruby/neo4j/driver/ext/internal/metrics/internal_connection_pool_metrics.rb +17 -0
- data/jruby/neo4j/driver/ext/internal/summary/internal_result_summary.rb +32 -0
- data/jruby/neo4j/driver/ext/internal_driver.rb +34 -0
- data/jruby/neo4j/driver/ext/internal_entity.rb +21 -0
- data/jruby/neo4j/driver/ext/internal_keys.rb +15 -0
- data/jruby/neo4j/driver/ext/internal_node.rb +13 -0
- data/jruby/neo4j/driver/ext/internal_record.rb +29 -0
- data/jruby/neo4j/driver/ext/internal_relationship.rb +13 -0
- data/jruby/neo4j/driver/ext/internal_result.rb +23 -0
- data/jruby/neo4j/driver/ext/internal_session.rb +40 -0
- data/jruby/neo4j/driver/ext/internal_transaction.rb +24 -0
- data/jruby/neo4j/driver/ext/logger.rb +60 -0
- data/jruby/neo4j/driver/ext/map_converter.rb +14 -0
- data/jruby/neo4j/driver/ext/neo_converter.rb +59 -0
- data/jruby/neo4j/driver/ext/query.rb +13 -0
- data/jruby/neo4j/driver/ext/ruby_converter.rb +57 -0
- data/jruby/neo4j/driver/ext/run_override.rb +22 -0
- data/jruby/neo4j/driver/ext/start_end_naming.rb +17 -0
- data/jruby/neo4j/driver.rb +54 -0
- data/lib/loader.rb +19 -0
- data/lib/neo4j/driver/auto_closable.rb +32 -0
- data/lib/neo4j/driver/exceptions/authentication_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/certificate_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/client_exception.rb +18 -0
- data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/database_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
- data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/neo4j_exception.rb +22 -0
- data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +17 -0
- data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/security_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +12 -0
- data/lib/neo4j/driver/exceptions/session_expired_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
- data/lib/neo4j/driver/exceptions/transient_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +11 -0
- data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
- data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
- data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
- data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +47 -0
- data/lib/neo4j/driver/internal/validator.rb +29 -0
- data/lib/neo4j/driver/summary/query_type.rb +12 -0
- data/lib/neo4j/driver/synchronizable.rb +23 -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 +15 -0
- metadata +336 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Exceptions
|
6
|
+
# A <em>SessionExpiredException</em> indicates that the session can no longer satisfy the criteria under which it
|
7
|
+
# was acquired, e.g. a server no longer accepts write requests. A new session needs to be acquired from the driver
|
8
|
+
# and all actions taken on the expired session must be replayed.
|
9
|
+
# @since 1.1
|
10
|
+
class SessionExpiredException < Neo4jException
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Exceptions
|
6
|
+
# The provided token has expired.
|
7
|
+
# <p>
|
8
|
+
# The current driver instance is considered invalid. It should not be used anymore. The client must create a new driver instance with a valid token.
|
9
|
+
# <p>
|
10
|
+
# Error code: Neo.ClientError.Security.TokenExpired
|
11
|
+
class TokenExpiredException < SecurityException
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Exceptions
|
6
|
+
# This exception indicates a user is nesting new transaction with an on-going transaction (unmanaged and/or auto-commit).
|
7
|
+
class TransactionNestingException < ClientException
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Exceptions
|
6
|
+
# A <em>TransientException</em> signals a temporary fault that may be worked around by retrying.
|
7
|
+
# The error code provided can be used to determine further detail for the problem.
|
8
|
+
# @since 1.0
|
9
|
+
class TransientException < Neo4jException
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Driver
|
3
|
+
module Exceptions
|
4
|
+
module Value
|
5
|
+
# A <em>LossyCoercion</em> exception indicates that the conversion cannot be achieved without losing precision.
|
6
|
+
# @since 1.0
|
7
|
+
class LossyCoercion < ValueException
|
8
|
+
def initialize(source_type_name, destination_type_name)
|
9
|
+
super("Cannot coerce #{source_type_name} to #{destination_type_name} without losing precision")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Driver
|
3
|
+
module Exceptions
|
4
|
+
module Value
|
5
|
+
# A <em>NotMultiValued</em> exception indicates that the value does not consist of multiple values, a.k.a. not a map
|
6
|
+
# or array.
|
7
|
+
# @since 1.0
|
8
|
+
class NotMultiValued < ValueException
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Driver
|
3
|
+
module Exceptions
|
4
|
+
module Value
|
5
|
+
# A <em>Uncoercible</em> exception indicates that the conversion cannot be achieved.
|
6
|
+
# @since 1.0
|
7
|
+
class Uncoercible < ValueException
|
8
|
+
def initialize(source_type_name, destination_type_name)
|
9
|
+
super("Cannot coerce #{source_type_name} to #{destination_type_name}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Driver
|
3
|
+
module Exceptions
|
4
|
+
module Value
|
5
|
+
# A <em>ValueException</em> indicates that the client has carried out an operation on values incorrectly.
|
6
|
+
# @since 1.0
|
7
|
+
class ValueException < ClientException
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
# Holds a host and port pair that denotes a Bolt server address.
|
4
|
+
class BoltServerAddress
|
5
|
+
attr_reader :host, :connection_host, :port
|
6
|
+
delegate :hash, to: :attributes
|
7
|
+
|
8
|
+
DEFAULT_PORT = 7687
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def host_from(uri)
|
12
|
+
uri&.host || (raise invalid_address_format(uri))
|
13
|
+
end
|
14
|
+
|
15
|
+
def port_from(uri)
|
16
|
+
uri&.port || DEFAULT_PORT
|
17
|
+
end
|
18
|
+
|
19
|
+
def uri_from(address)
|
20
|
+
scheme_split = address.split('://')
|
21
|
+
|
22
|
+
if scheme_split.length == 1
|
23
|
+
# URI can't parse addresses without scheme, prepend fake "bolt://" to reuse the parsing facility
|
24
|
+
scheme = 'bolt://'
|
25
|
+
host_port = host_port_from(scheme_split.first)
|
26
|
+
elsif scheme_split.length == 2
|
27
|
+
scheme = "#{scheme_split.first}://"
|
28
|
+
host_port = host_port_from(scheme_split.second)
|
29
|
+
else
|
30
|
+
raise invalid_address_format(address)
|
31
|
+
end
|
32
|
+
|
33
|
+
URI(scheme + host_port)
|
34
|
+
end
|
35
|
+
|
36
|
+
def host_port_from(address)
|
37
|
+
# expected to be an IPv6 address like [::1] or [::1]:7687
|
38
|
+
return address if address.start_with?('[')
|
39
|
+
|
40
|
+
contains_single_colon = address.index(':') == address.rindex(':')
|
41
|
+
|
42
|
+
# expected to be an IPv4 address with or without port like 127.0.0.1 or 127.0.0.1:7687
|
43
|
+
return address if contains_single_colon
|
44
|
+
|
45
|
+
# address contains multiple colons and does not start with '['
|
46
|
+
# expected to be an IPv6 address without brackets
|
47
|
+
"[#{address}]"
|
48
|
+
end
|
49
|
+
|
50
|
+
def invalid_address_format(address)
|
51
|
+
ArgumentError.new("Invalid address format #{address}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def require_valid_port(port)
|
55
|
+
return port if port >= 0 && port <= 65_535
|
56
|
+
|
57
|
+
raise ArgumentError, "Illegal port: #{port}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(uri: nil, host: self.class.host_from(uri), port: self.class.port_from(uri), connection_host: host)
|
62
|
+
@host = Validator.require_non_nil!(host)
|
63
|
+
@connection_host = Validator.require_non_nil!(connection_host)
|
64
|
+
@port = self.class.require_valid_port(port)
|
65
|
+
end
|
66
|
+
|
67
|
+
LOCAL_DEFAULT = new(host: 'localhost', port: DEFAULT_PORT)
|
68
|
+
|
69
|
+
def self.from(address)
|
70
|
+
address.is_a?(BoltServerAddress) ? address : new(address.host, address.port)
|
71
|
+
end
|
72
|
+
|
73
|
+
def eql?(other)
|
74
|
+
attributes.eql?(other&.attributes)
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
"#{host}#{"(#{connection_host})" unless host == connection_host}:#{port}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create a stream of unicast addresses.
|
82
|
+
# <p>
|
83
|
+
# While this implementation just returns a stream of itself, the subclasses may provide multiple addresses.
|
84
|
+
|
85
|
+
# @return stream of unicast addresses.
|
86
|
+
def unicast_stream
|
87
|
+
[self]
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def attributes
|
93
|
+
[@host, @connection_host, @port]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Internal
|
6
|
+
module DurationNormalizer
|
7
|
+
class << self
|
8
|
+
def normalize(object)
|
9
|
+
parts = object.parts.to_h
|
10
|
+
parts.default = 0
|
11
|
+
months_i, months_remainder_seconds = divmod(months(parts), ActiveSupport::Duration::SECONDS_PER_MONTH)
|
12
|
+
months_days, months_remainder_seconds =
|
13
|
+
months_remainder_seconds.divmod(ActiveSupport::Duration::SECONDS_PER_DAY)
|
14
|
+
days_i, days_remainder_seconds = divmod(months_days + days(parts), ActiveSupport::Duration::SECONDS_PER_DAY)
|
15
|
+
seconds_i, nonanoseconds = divmod(months_remainder_seconds + days_remainder_seconds + seconds(parts),
|
16
|
+
1_000_000_000)
|
17
|
+
[months_i, days_i, seconds_i, nonanoseconds.round]
|
18
|
+
end
|
19
|
+
|
20
|
+
def milliseconds(duration)
|
21
|
+
duration&.in_milliseconds&.round
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def divmod(number, factor)
|
27
|
+
number_i, remainder = number.divmod(1)
|
28
|
+
[number_i.to_i, remainder * factor]
|
29
|
+
end
|
30
|
+
|
31
|
+
def months(parts)
|
32
|
+
parts[:years] * 12 + parts[:months]
|
33
|
+
end
|
34
|
+
|
35
|
+
def days(parts)
|
36
|
+
parts[:weeks] * 7 + parts[:days]
|
37
|
+
end
|
38
|
+
|
39
|
+
def seconds(parts)
|
40
|
+
parts[:hours] * ActiveSupport::Duration::SECONDS_PER_HOUR +
|
41
|
+
parts[:minutes] * ActiveSupport::Duration::SECONDS_PER_MINUTE + parts[:seconds]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Internal
|
6
|
+
module Validator
|
7
|
+
def self.require_hash_parameters!(parameters)
|
8
|
+
require_hash!(parameters) do
|
9
|
+
"The parameters should be provided as Map type. Unsupported parameters type: #{parameters.class.name}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.require_hash!(obj)
|
14
|
+
raise(ArgumentError, yield) unless obj.nil? || obj.is_a?(Hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.require_non_nil!(obj, message = nil)
|
18
|
+
raise ArgumentError, [message, "can't be nil"].compact.join(' ') if obj.nil?
|
19
|
+
obj
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.require_non_nil_credentials!(username, password)
|
23
|
+
require_non_nil! username, "Username"
|
24
|
+
require_non_nil! password, "Password"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Synchronizable
|
6
|
+
def sync(*methods)
|
7
|
+
prepend with_sync_wrapper(methods)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def with_sync_wrapper(methods)
|
13
|
+
Module.new do
|
14
|
+
methods.each do |method|
|
15
|
+
define_method(method) do |*args, **kwargs, &block|
|
16
|
+
Sync { super(*args, **kwargs, &block) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Types
|
6
|
+
class LocalDateTime < Time
|
7
|
+
class << self
|
8
|
+
FIELDS = %i[year month day hour min sec nsec].freeze
|
9
|
+
|
10
|
+
def significant_fields
|
11
|
+
FIELDS
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate(*significant_fields, to: :@time)
|
16
|
+
delegate :to_i, to: :@time
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Types
|
6
|
+
class LocalTime < Time
|
7
|
+
class << self
|
8
|
+
FIELDS = %i[hour min sec nsec].freeze
|
9
|
+
|
10
|
+
def significant_fields
|
11
|
+
FIELDS
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate(*significant_fields, to: :@time)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Types
|
6
|
+
class OffsetTime < Time
|
7
|
+
class << self
|
8
|
+
FIELDS = %i[hour min sec nsec utc_offset].freeze
|
9
|
+
|
10
|
+
def significant_fields
|
11
|
+
FIELDS
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate(*significant_fields, to: :@time)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Types
|
6
|
+
class Point
|
7
|
+
attr_accessor :srid, :x, :y, :z
|
8
|
+
|
9
|
+
SRID = {
|
10
|
+
'WGS-84': 4326,
|
11
|
+
'WGS-84-3D': 4979,
|
12
|
+
cartesian: 7203,
|
13
|
+
'cartesian-3D': 9157
|
14
|
+
}.with_indifferent_access.freeze
|
15
|
+
|
16
|
+
def initialize(args)
|
17
|
+
self.x = args[:longitude] || args[:x]
|
18
|
+
self.y = args[:latitude] || args[:y]
|
19
|
+
self.z = args[:height] || args[:z]
|
20
|
+
self.srid = args[:srid] || SRID[args[:crs] || implied_crs(args[:longitude] || args[:latitude])]
|
21
|
+
end
|
22
|
+
|
23
|
+
def coordinates
|
24
|
+
[x, y, z].compact.map(&:to_f)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def implied_crs(geo)
|
30
|
+
if geo
|
31
|
+
z ? :'WGS-84-3D' : :'WGS-84'
|
32
|
+
else
|
33
|
+
z ? :'cartesian-3D' : :cartesian
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
module Types
|
6
|
+
class Time
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
delegate :hash, :to_a, to: :significant
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def parse(date)
|
13
|
+
new(::Time.parse(date))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(time)
|
18
|
+
@time = time
|
19
|
+
end
|
20
|
+
|
21
|
+
def significant
|
22
|
+
self.class.significant_fields.map(&method(:send))
|
23
|
+
end
|
24
|
+
|
25
|
+
def <=>(other)
|
26
|
+
return unless other.is_a?(self.class)
|
27
|
+
|
28
|
+
self.class.significant_fields.reduce(0) do |acc, elem|
|
29
|
+
acc.zero? ? send(elem) <=> other.send(elem) : (break acc)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def eql?(other)
|
34
|
+
other.is_a?(self.class) && self.class.significant_fields.all? { |elem| send(elem).eql?(other.send(elem)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def +(numeric)
|
38
|
+
self.class.new(@time + numeric)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'active_support/concern'
|
9
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
10
|
+
require 'active_support/isolated_execution_state' if Gem::Requirement.create('>= 7').satisfied_by?(Gem.loaded_specs["activesupport"].version) # TODO: this should not be necessary https://github.com/rails/rails/issues/43851
|
11
|
+
require 'active_support/core_ext/numeric/time'
|
12
|
+
require 'active_support/duration'
|
13
|
+
require 'active_support/time'
|
14
|
+
require 'neo4j/driver'
|
15
|
+
require 'uri'
|