neo4j-ruby-driver 0.1.1

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