neo4j-ruby-driver 4.4.0-java

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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +72 -0
  4. data/jruby/neo4j/driver/ext/async_converter.rb +55 -0
  5. data/jruby/neo4j/driver/ext/auth_tokens.rb +20 -0
  6. data/jruby/neo4j/driver/ext/bookmark.rb +15 -0
  7. data/jruby/neo4j/driver/ext/config_converter.rb +69 -0
  8. data/jruby/neo4j/driver/ext/exception_checkable.rb +34 -0
  9. data/jruby/neo4j/driver/ext/exception_mapper.rb +89 -0
  10. data/jruby/neo4j/driver/ext/graph_database.rb +29 -0
  11. data/jruby/neo4j/driver/ext/internal/async/internal_async_session.rb +23 -0
  12. data/jruby/neo4j/driver/ext/internal/cluster/routing_table_registry_impl.rb +15 -0
  13. data/jruby/neo4j/driver/ext/internal/cursor/disposable_async_result_cursor.rb +15 -0
  14. data/jruby/neo4j/driver/ext/internal/metrics/internal_connection_pool_metrics.rb +17 -0
  15. data/jruby/neo4j/driver/ext/internal/summary/internal_result_summary.rb +32 -0
  16. data/jruby/neo4j/driver/ext/internal_driver.rb +34 -0
  17. data/jruby/neo4j/driver/ext/internal_entity.rb +21 -0
  18. data/jruby/neo4j/driver/ext/internal_keys.rb +15 -0
  19. data/jruby/neo4j/driver/ext/internal_node.rb +13 -0
  20. data/jruby/neo4j/driver/ext/internal_record.rb +29 -0
  21. data/jruby/neo4j/driver/ext/internal_relationship.rb +13 -0
  22. data/jruby/neo4j/driver/ext/internal_result.rb +23 -0
  23. data/jruby/neo4j/driver/ext/internal_session.rb +40 -0
  24. data/jruby/neo4j/driver/ext/internal_transaction.rb +24 -0
  25. data/jruby/neo4j/driver/ext/logger.rb +60 -0
  26. data/jruby/neo4j/driver/ext/map_converter.rb +14 -0
  27. data/jruby/neo4j/driver/ext/neo_converter.rb +59 -0
  28. data/jruby/neo4j/driver/ext/query.rb +13 -0
  29. data/jruby/neo4j/driver/ext/ruby_converter.rb +57 -0
  30. data/jruby/neo4j/driver/ext/run_override.rb +22 -0
  31. data/jruby/neo4j/driver/ext/start_end_naming.rb +17 -0
  32. data/jruby/neo4j/driver.rb +54 -0
  33. data/lib/loader.rb +19 -0
  34. data/lib/neo4j/driver/auto_closable.rb +32 -0
  35. data/lib/neo4j/driver/exceptions/authentication_exception.rb +15 -0
  36. data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
  37. data/lib/neo4j/driver/exceptions/certificate_exception.rb +10 -0
  38. data/lib/neo4j/driver/exceptions/client_exception.rb +18 -0
  39. data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
  40. data/lib/neo4j/driver/exceptions/database_exception.rb +13 -0
  41. data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
  42. data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
  43. data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
  44. data/lib/neo4j/driver/exceptions/neo4j_exception.rb +22 -0
  45. data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
  46. data/lib/neo4j/driver/exceptions/protocol_exception.rb +17 -0
  47. data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
  48. data/lib/neo4j/driver/exceptions/security_exception.rb +14 -0
  49. data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +12 -0
  50. data/lib/neo4j/driver/exceptions/session_expired_exception.rb +14 -0
  51. data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
  52. data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
  53. data/lib/neo4j/driver/exceptions/transient_exception.rb +13 -0
  54. data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +11 -0
  55. data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
  56. data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
  57. data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
  58. data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
  59. data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
  60. data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
  61. data/lib/neo4j/driver/internal/duration_normalizer.rb +47 -0
  62. data/lib/neo4j/driver/internal/validator.rb +29 -0
  63. data/lib/neo4j/driver/summary/query_type.rb +12 -0
  64. data/lib/neo4j/driver/synchronizable.rb +23 -0
  65. data/lib/neo4j/driver/types/local_date_time.rb +20 -0
  66. data/lib/neo4j/driver/types/local_time.rb +19 -0
  67. data/lib/neo4j/driver/types/offset_time.rb +19 -0
  68. data/lib/neo4j/driver/types/point.rb +39 -0
  69. data/lib/neo4j/driver/types/time.rb +43 -0
  70. data/lib/neo4j/driver/version.rb +7 -0
  71. data/lib/neo4j_ruby_driver.rb +15 -0
  72. 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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ # Thrown if the remote server cannot be verified as Neo4j.
7
+ class UntrustedServerException < RuntimeError
8
+ end
9
+ end
10
+ end
11
+ 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
+ # An <em>Unsizable</em> exception indicates that the value does not have a size.
6
+ # @since 1.0
7
+ class Unsizable < ValueException
8
+ end
9
+ end
10
+ end
11
+ end
12
+ 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,12 @@
1
+ module Neo4j
2
+ module Driver
3
+ module Summary
4
+ module QueryType
5
+ READ_ONLY = 'r'
6
+ READ_WRITE = 'rw'
7
+ WRITE_ONLY = 'w'
8
+ SCHEMA_WRITE = 's'
9
+ end
10
+ end
11
+ end
12
+ 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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ VERSION = '4.4.0'
6
+ end
7
+ 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'