neo4j-ruby-driver 0.1.1

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 (103) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +68 -0
  5. data/Rakefile +16 -0
  6. data/ffi/bolt/address.rb +11 -0
  7. data/ffi/bolt/auth.rb +10 -0
  8. data/ffi/bolt/auto_releasable.rb +22 -0
  9. data/ffi/bolt/boolean.rb +9 -0
  10. data/ffi/bolt/bytes.rb +10 -0
  11. data/ffi/bolt/config.rb +10 -0
  12. data/ffi/bolt/connection.rb +44 -0
  13. data/ffi/bolt/connector.rb +17 -0
  14. data/ffi/bolt/dictionary.rb +15 -0
  15. data/ffi/bolt/error.rb +74 -0
  16. data/ffi/bolt/float.rb +9 -0
  17. data/ffi/bolt/integer.rb +9 -0
  18. data/ffi/bolt/library.rb +12 -0
  19. data/ffi/bolt/lifecycle.rb +9 -0
  20. data/ffi/bolt/list.rb +10 -0
  21. data/ffi/bolt/status.rb +15 -0
  22. data/ffi/bolt/string.rb +9 -0
  23. data/ffi/bolt/structure.rb +10 -0
  24. data/ffi/bolt/value.rb +35 -0
  25. data/ffi/bolt/values_private.rb +36 -0
  26. data/ffi/neo4j/driver.rb +45 -0
  27. data/ffi/neo4j/driver/access_mode.rb +10 -0
  28. data/ffi/neo4j/driver/auth_tokens.rb +17 -0
  29. data/ffi/neo4j/driver/config.rb +11 -0
  30. data/ffi/neo4j/driver/graph_database.rb +29 -0
  31. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +19 -0
  32. data/ffi/neo4j/driver/internal/async/direct_connection.rb +88 -0
  33. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +30 -0
  34. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +27 -0
  35. data/ffi/neo4j/driver/internal/driver_factory.rb +38 -0
  36. data/ffi/neo4j/driver/internal/error_handling.rb +50 -0
  37. data/ffi/neo4j/driver/internal/explicit_transaction.rb +144 -0
  38. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +101 -0
  39. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +46 -0
  40. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +32 -0
  41. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +32 -0
  42. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +23 -0
  43. data/ffi/neo4j/driver/internal/internal_driver.rb +41 -0
  44. data/ffi/neo4j/driver/internal/internal_record.rb +22 -0
  45. data/ffi/neo4j/driver/internal/internal_statement_result.rb +52 -0
  46. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +24 -0
  47. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +59 -0
  48. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +16 -0
  49. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +63 -0
  50. data/ffi/neo4j/driver/internal/network_session.rb +124 -0
  51. data/ffi/neo4j/driver/internal/session_factory_impl.rb +28 -0
  52. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +67 -0
  53. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +19 -0
  54. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +23 -0
  55. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +15 -0
  56. data/ffi/neo4j/driver/internal/value/base_time_value.rb +22 -0
  57. data/ffi/neo4j/driver/internal/value/date_value.rb +25 -0
  58. data/ffi/neo4j/driver/internal/value/duration_value.rb +27 -0
  59. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +24 -0
  60. data/ffi/neo4j/driver/internal/value/local_time_value.rb +19 -0
  61. data/ffi/neo4j/driver/internal/value/node_value.rb +18 -0
  62. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +25 -0
  63. data/ffi/neo4j/driver/internal/value/path_value.rb +41 -0
  64. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +24 -0
  65. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +24 -0
  66. data/ffi/neo4j/driver/internal/value/relationship_value.rb +18 -0
  67. data/ffi/neo4j/driver/internal/value/structure_value.rb +42 -0
  68. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +25 -0
  69. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +28 -0
  70. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +18 -0
  71. data/ffi/neo4j/driver/internal/value/value_adapter.rb +95 -0
  72. data/ffi/neo4j/driver/statement.rb +14 -0
  73. data/ffi/neo4j/driver/summary/statement_type.rb +14 -0
  74. data/ffi/neo4j/driver/types/entity.rb +17 -0
  75. data/ffi/neo4j/driver/types/node.rb +16 -0
  76. data/ffi/neo4j/driver/types/path.rb +35 -0
  77. data/ffi/neo4j/driver/types/relationship.rb +19 -0
  78. data/lib/loader.rb +18 -0
  79. data/lib/neo4j/driver/auto_closable.rb +32 -0
  80. data/lib/neo4j/driver/exceptions/authentication_exception.rb +10 -0
  81. data/lib/neo4j/driver/exceptions/client_exception.rb +10 -0
  82. data/lib/neo4j/driver/exceptions/database_exception.rb +10 -0
  83. data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
  84. data/lib/neo4j/driver/exceptions/neo4j_exception.rb +18 -0
  85. data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
  86. data/lib/neo4j/driver/exceptions/protocol_exception.rb +10 -0
  87. data/lib/neo4j/driver/exceptions/security_exception.rb +10 -0
  88. data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +10 -0
  89. data/lib/neo4j/driver/exceptions/session_expired_exception.rb +10 -0
  90. data/lib/neo4j/driver/exceptions/transient_exception.rb +10 -0
  91. data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +10 -0
  92. data/lib/neo4j/driver/internal/duration_normalizer.rb +42 -0
  93. data/lib/neo4j/driver/internal/ruby_signature.rb +18 -0
  94. data/lib/neo4j/driver/types/byte_array.rb +17 -0
  95. data/lib/neo4j/driver/types/local_date_time.rb +20 -0
  96. data/lib/neo4j/driver/types/local_time.rb +19 -0
  97. data/lib/neo4j/driver/types/offset_time.rb +19 -0
  98. data/lib/neo4j/driver/types/point.rb +39 -0
  99. data/lib/neo4j/driver/types/time.rb +43 -0
  100. data/lib/neo4j/driver/version.rb +7 -0
  101. data/lib/neo4j_ruby_driver.rb +19 -0
  102. data/neo4j-ruby-driver.gemspec +63 -0
  103. metadata +274 -0
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ class Statement
6
+ attr_reader :text, :parameters
7
+
8
+ def initialize(text, parameters = {})
9
+ @text = text
10
+ @parameters = parameters
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Summary
6
+ module StatementType
7
+ READ_ONLY = 'r'
8
+ READ_WRITE = 'rw'
9
+ WRITE_ONLY = 'w'
10
+ SCHEMA_WRITE = 's'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Types
6
+ class Entity
7
+ attr_reader :id, :properties
8
+ delegate :[], to: :properties
9
+
10
+ def initialize(id, properties)
11
+ @id = id
12
+ @properties = properties
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Types
6
+ class Node < Entity
7
+ attr_reader :labels
8
+
9
+ def initialize(id, labels, properties)
10
+ super(id, properties)
11
+ @labels = labels
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Types
6
+ class Path < Array
7
+ attr_reader :modes, :relationships
8
+
9
+ class Segment
10
+ attr_reader :start_node, :relationship, :end_node
11
+
12
+ def initialize(start_node, relationship, end_node)
13
+ @start_node = start_node
14
+ @relationship = relationship
15
+ @end_node = end_node
16
+ end
17
+ end
18
+
19
+ def initialize(nodes, relationships)
20
+ super()
21
+ @nodes = nodes
22
+ @relationships = relationships
23
+ end
24
+
25
+ def start_node
26
+ @nodes.first
27
+ end
28
+
29
+ def end_node
30
+ @nodes.last
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Types
6
+ class Relationship < Entity
7
+ attr_accessor :start_node_id, :end_node_id
8
+ attr_reader :type
9
+
10
+ def initialize(id, start_node_id, end_node_id, type, properties)
11
+ super(id, properties)
12
+ @start_node_id = start_node_id
13
+ @end_node_id = end_node_id
14
+ @type = type
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zeitwerk'
4
+
5
+ class Loader
6
+ def self.load
7
+ loader = Zeitwerk::Loader.new
8
+ loader.tag = 'neo4j-ruby-driver'
9
+ loader.push_dir(File.expand_path(__dir__))
10
+ loader.push_dir(File.dirname(File.dirname(caller_locations(1..1).first.path)))
11
+ loader.ignore(File.expand_path('neo4j-java-driver_jars.rb', __dir__))
12
+ loader.ignore(File.expand_path('neo4j_ruby_driver.rb', __dir__))
13
+ loader.ignore(File.expand_path('org', __dir__))
14
+ loader.inflector = Zeitwerk::GemInflector.new(File.expand_path('neo4j/driver', __dir__))
15
+ loader.setup
16
+ loader.eager_load
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module AutoClosable
6
+ def auto_closable(*methods)
7
+ prepend with_block_definer(methods)
8
+ end
9
+
10
+ private
11
+
12
+ def with_block_definer(methods)
13
+ Module.new do
14
+ methods.each do |method|
15
+ define_method(method) do |*args, &block|
16
+ closable = super(*args)
17
+ if block
18
+ begin
19
+ block.arity.zero? ? closable.instance_eval(&block) : block.call(closable)
20
+ ensure
21
+ closable&.close
22
+ end
23
+ else
24
+ closable
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class AuthenticationException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class ClientException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class DatabaseException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class IllegalStateException < RuntimeError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class Neo4jException < RuntimeError
7
+ attr_reader :code, :cause
8
+
9
+ def initialize(*args)
10
+ @code = args.shift if args.count > 1
11
+ message = args.shift
12
+ @cause = args.shift
13
+ super(message)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class NoSuchRecordException < RuntimeError
7
+ EMPTY = 'Cannot retrieve a single record, because this result is empty.'
8
+ TOO_MANY = 'Expected a result with a single record, but this result ' \
9
+ 'contains at least one more. Ensure your query returns only one record.'
10
+ NO_MORE = 'No more records'
11
+ NO_PEEK_PAST = 'Cannot peek past the last record'
12
+
13
+ class << self
14
+ def empty
15
+ new(EMPTY)
16
+ end
17
+
18
+ def too_many
19
+ new(TOO_MANY)
20
+ end
21
+
22
+ def no_more
23
+ new(NO_MORE)
24
+ end
25
+
26
+ def no_peek_past
27
+ new(NO_PEEK_PAST)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class ProtocolException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class SecurityException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class ServiceUnavailableException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class SessionExpiredException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class TransientException < Neo4jException
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Exceptions
6
+ class UntrustedServerException < RuntimeError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,42 @@
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
10
+ months_i, months_remainder_seconds = divmod(months(parts), ActiveSupport::Duration::SECONDS_PER_MONTH)
11
+ months_days, months_remainder_seconds =
12
+ months_remainder_seconds.divmod(ActiveSupport::Duration::SECONDS_PER_DAY)
13
+ days_i, days_remainder_seconds = divmod(months_days + days(parts), ActiveSupport::Duration::SECONDS_PER_DAY)
14
+ seconds_i, nonanoseconds = divmod(months_remainder_seconds + days_remainder_seconds + seconds(parts),
15
+ 1_000_000_000)
16
+ [months_i, days_i, seconds_i, nonanoseconds.round]
17
+ end
18
+
19
+ private
20
+
21
+ def divmod(number, factor)
22
+ number_i, remainder = number.divmod(1)
23
+ [number_i.to_i, remainder * factor]
24
+ end
25
+
26
+ def months(parts)
27
+ parts[:years] * 12 + parts[:months]
28
+ end
29
+
30
+ def days(parts)
31
+ parts[:weeks] * 7 + parts[:days]
32
+ end
33
+
34
+ def seconds(parts)
35
+ parts[:hours] * ActiveSupport::Duration::SECONDS_PER_HOUR +
36
+ parts[:minutes] * ActiveSupport::Duration::SECONDS_PER_MINUTE + parts[:seconds]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module RubySignature
7
+ class << self
8
+ def session(args)
9
+ [
10
+ args.empty? || args.first.is_a?(String) ? Neo4j::Driver::AccessMode::WRITE : args.shift, # mode
11
+ args # bookmarks
12
+ ]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Types
6
+ class ByteArray < String
7
+ def self.from_bytes(bytes)
8
+ new(bytes.pack('C*'))
9
+ end
10
+
11
+ def to_bytes
12
+ unpack('C*')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ 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