neo4j-ruby-driver 4.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
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'