neospace 0.0.1 → 1.7.0

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +88 -0
  4. data/ffi/bolt/address.rb +11 -0
  5. data/ffi/bolt/address_resolver.rb +12 -0
  6. data/ffi/bolt/address_set.rb +9 -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 +45 -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/log.rb +16 -0
  22. data/ffi/bolt/socket_options.rb +14 -0
  23. data/ffi/bolt/status.rb +25 -0
  24. data/ffi/bolt/string.rb +9 -0
  25. data/ffi/bolt/structure.rb +10 -0
  26. data/ffi/bolt/value.rb +35 -0
  27. data/ffi/neo4j/driver.rb +60 -0
  28. data/ffi/neo4j/driver/access_mode.rb +10 -0
  29. data/ffi/neo4j/driver/auth_tokens.rb +18 -0
  30. data/ffi/neo4j/driver/config.rb +40 -0
  31. data/ffi/neo4j/driver/graph_database.rb +52 -0
  32. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +19 -0
  33. data/ffi/neo4j/driver/internal/async/direct_connection.rb +106 -0
  34. data/ffi/neo4j/driver/internal/bolt_server_address.rb +18 -0
  35. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +30 -0
  36. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +28 -0
  37. data/ffi/neo4j/driver/internal/driver_factory.rb +125 -0
  38. data/ffi/neo4j/driver/internal/error_handling.rb +108 -0
  39. data/ffi/neo4j/driver/internal/explicit_transaction.rb +146 -0
  40. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +105 -0
  41. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +49 -0
  42. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +32 -0
  43. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +32 -0
  44. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +23 -0
  45. data/ffi/neo4j/driver/internal/internal_driver.rb +45 -0
  46. data/ffi/neo4j/driver/internal/internal_logger.rb +32 -0
  47. data/ffi/neo4j/driver/internal/internal_record.rb +26 -0
  48. data/ffi/neo4j/driver/internal/internal_resolver.rb +31 -0
  49. data/ffi/neo4j/driver/internal/internal_statement_result.rb +52 -0
  50. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +24 -0
  51. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +59 -0
  52. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +16 -0
  53. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +63 -0
  54. data/ffi/neo4j/driver/internal/network_session.rb +129 -0
  55. data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +80 -0
  56. data/ffi/neo4j/driver/internal/session_factory_impl.rb +28 -0
  57. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +67 -0
  58. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +19 -0
  59. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +23 -0
  60. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +15 -0
  61. data/ffi/neo4j/driver/internal/value/base_time_value.rb +22 -0
  62. data/ffi/neo4j/driver/internal/value/date_value.rb +25 -0
  63. data/ffi/neo4j/driver/internal/value/duration_value.rb +27 -0
  64. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +24 -0
  65. data/ffi/neo4j/driver/internal/value/local_time_value.rb +19 -0
  66. data/ffi/neo4j/driver/internal/value/node_value.rb +18 -0
  67. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +25 -0
  68. data/ffi/neo4j/driver/internal/value/path_value.rb +41 -0
  69. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +24 -0
  70. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +24 -0
  71. data/ffi/neo4j/driver/internal/value/relationship_value.rb +18 -0
  72. data/ffi/neo4j/driver/internal/value/structure_value.rb +42 -0
  73. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +25 -0
  74. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +28 -0
  75. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +18 -0
  76. data/ffi/neo4j/driver/internal/value/value_adapter.rb +99 -0
  77. data/ffi/neo4j/driver/net/server_address.rb +13 -0
  78. data/ffi/neo4j/driver/statement.rb +15 -0
  79. data/ffi/neo4j/driver/summary/statement_type.rb +14 -0
  80. data/ffi/neo4j/driver/types/entity.rb +21 -0
  81. data/ffi/neo4j/driver/types/node.rb +16 -0
  82. data/ffi/neo4j/driver/types/path.rb +35 -0
  83. data/ffi/neo4j/driver/types/relationship.rb +19 -0
  84. data/lib/loader.rb +18 -0
  85. data/lib/neo4j/driver/auto_closable.rb +32 -0
  86. data/lib/neo4j/driver/exceptions/authentication_exception.rb +10 -0
  87. data/lib/neo4j/driver/exceptions/client_exception.rb +15 -0
  88. data/lib/neo4j/driver/exceptions/database_exception.rb +10 -0
  89. data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
  90. data/lib/neo4j/driver/exceptions/neo4j_exception.rb +23 -0
  91. data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
  92. data/lib/neo4j/driver/exceptions/protocol_exception.rb +10 -0
  93. data/lib/neo4j/driver/exceptions/security_exception.rb +10 -0
  94. data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +10 -0
  95. data/lib/neo4j/driver/exceptions/session_expired_exception.rb +10 -0
  96. data/lib/neo4j/driver/exceptions/transient_exception.rb +10 -0
  97. data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +10 -0
  98. data/lib/neo4j/driver/internal/duration_normalizer.rb +46 -0
  99. data/lib/neo4j/driver/internal/ruby_signature.rb +18 -0
  100. data/lib/neo4j/driver/internal/validator.rb +28 -0
  101. data/lib/neo4j/driver/types/bytes.rb +10 -0
  102. data/lib/neo4j/driver/types/local_date_time.rb +20 -0
  103. data/lib/neo4j/driver/types/local_time.rb +19 -0
  104. data/lib/neo4j/driver/types/offset_time.rb +19 -0
  105. data/lib/neo4j/driver/types/point.rb +39 -0
  106. data/lib/neo4j/driver/types/time.rb +43 -0
  107. data/lib/neo4j/driver/version.rb +7 -0
  108. data/lib/neo4j_ruby_driver.rb +20 -0
  109. metadata +314 -12
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Summary
7
+ class InternalServerInfo
8
+ attr_reader :address, :version
9
+
10
+ def initialize(bolt_connection)
11
+ address = Bolt::Connection.remote_endpoint(bolt_connection)
12
+ @address = %i[host port].map { |method| Bolt::Address.send(method, address).first }.join(':')
13
+ @version = Bolt::Connection.server(bolt_connection).first
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Summary
7
+ class InternalSummaryCounters
8
+ def initialize(stats)
9
+ @stats = stats || RecursiveOpenStruct.new
10
+ end
11
+
12
+ def contains_updates?
13
+ @stats.to_h.values.any?(&:positive?)
14
+ end
15
+
16
+ def method_missing(method)
17
+ @stats.send(method) || 0
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Util
7
+ class MetadataExtractor
8
+ def initialize(result_available_after_metadata_key, result_consumed_after_metadata_key); end
9
+
10
+ def extract_bookmarks(metadata); end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module BaseTimeValue
8
+ NANO_FACTOR = 1_000_000_000
9
+
10
+ def time(nano_of_day_local, offset_seconds = nil)
11
+ min, sec = Rational(nano_of_day_local, NANO_FACTOR).divmod(60)
12
+ Time.new(0, 1, 1, *min.divmod(60), sec, offset_seconds)
13
+ end
14
+
15
+ def to_neo_values(local_time)
16
+ ((local_time.hour * 60 + local_time.min) * 60 + local_time.sec) * NANO_FACTOR + local_time.nsec
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module DateValue
8
+ CODE = :D
9
+ extend StructureValue
10
+ EPOCH = Date.parse('1970-01-01')
11
+
12
+ class << self
13
+ def to_ruby_value(epoch_day)
14
+ EPOCH + epoch_day
15
+ end
16
+
17
+ def to_neo_values(date)
18
+ (date - EPOCH).to_i
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module DurationValue
8
+ CODE = :E
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(months, days, seconds, nanoseconds)
13
+ ActiveSupport::Duration.months(months) +
14
+ ActiveSupport::Duration.days(days) +
15
+ ActiveSupport::Duration.seconds(seconds) +
16
+ ActiveSupport::Duration.seconds(nanoseconds * BigDecimal('1e-9'))
17
+ end
18
+
19
+ def to_neo_values(object)
20
+ DurationNormalizer.normalize(object)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module LocalDateTimeValue
8
+ CODE = :d
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(epoch_second_utc, nsec)
13
+ Types::LocalDateTime.new(Time.at(epoch_second_utc, nsec, :nsec).utc)
14
+ end
15
+
16
+ def to_neo_values(local_date_time)
17
+ [local_date_time.to_i, local_date_time.nsec]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module LocalTimeValue
8
+ CODE = :t
9
+ extend StructureValue
10
+ extend BaseTimeValue
11
+
12
+ def self.to_ruby_value(nano_of_day_local)
13
+ Types::LocalTime.new(time(nano_of_day_local))
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module NodeValue
8
+ CODE = :N
9
+ extend StructureValue
10
+
11
+ def self.to_ruby_value(id, labels, properties)
12
+ Types::Node.new(id, labels.map(&:to_sym), properties)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module OffsetTimeValue
8
+ CODE = :T
9
+ extend StructureValue
10
+ extend BaseTimeValue
11
+
12
+ class << self
13
+ def to_ruby_value(nano_of_day_local, offset_seconds)
14
+ Types::OffsetTime.new(time(nano_of_day_local, offset_seconds))
15
+ end
16
+
17
+ def to_neo_values(offset_time)
18
+ [super, offset_time.utc_offset]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module PathValue
8
+ CODE = :P
9
+ extend StructureValue
10
+ class << self
11
+ def to_ruby_value(uniq_nodes, uniq_rels, sequence)
12
+ prev_node = uniq_nodes.first
13
+ nodes = [prev_node] # Start node is always 0, and isn't encoded in the sequence
14
+ rels = []
15
+ path = Types::Path.new(nodes, rels)
16
+ sequence.in_groups_of(2) do |node_idx, rel_idx|
17
+ node = uniq_nodes[node_idx]
18
+ nodes << node
19
+ rel = uniq_rels[rel_idx.abs - 1] # -1 because rel idx are 1-indexed
20
+ update(rel, prev_node, node, rel_idx.negative?)
21
+ rels << rel
22
+ path << Types::Path::Segment.new(prev_node, rel, node)
23
+ prev_node = node
24
+ end
25
+ path
26
+ end
27
+
28
+ private
29
+
30
+ def update(rel, prev_node, node, inversed)
31
+ # Negative rel index means this rel was traversed "inversed" from its direction
32
+ prev_node, node = node, prev_node if inversed
33
+ rel.start_node_id = prev_node.id
34
+ rel.end_node_id = node.id
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module Point2DValue
8
+ CODE = :X
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(srid, x, y)
13
+ Types::Point.new(srid: srid, x: x, y: y)
14
+ end
15
+
16
+ def to_neo_values(point)
17
+ [point.srid.to_i, *point.coordinates]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module Point3DValue
8
+ CODE = :Y
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(srid, x, y, z)
13
+ Types::Point.new(srid: srid, x: x, y: y, z: z)
14
+ end
15
+
16
+ def to_neo_values(point)
17
+ [point.srid.to_i, *point.coordinates]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module RelationshipValue
8
+ CODE = :R
9
+ extend StructureValue
10
+
11
+ def self.to_ruby_value(id, start_node_id, end_node_id, type, properties)
12
+ Types::Relationship.new(id, start_node_id, end_node_id, type, properties)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module StructureValue
8
+ def self.extended(mod)
9
+ code = mod.const_get('CODE').to_s.getbyte(0)
10
+ (@modules ||= {})[code] = mod
11
+ mod.define_singleton_method(:code) { code }
12
+ end
13
+
14
+ def self.to_ruby(value)
15
+ @modules[Bolt::Structure.code(value)]&.to_ruby_specific(value)
16
+ end
17
+
18
+ def to_ruby_specific(value)
19
+ to_ruby_value(*Array.new(size, &method(:ruby_value).curry.call(value)))
20
+ end
21
+
22
+ def to_neo(value, object)
23
+ Bolt::Value.format_as_structure(value, code, size)
24
+ Array(to_neo_values(object)).each_with_index do |elem, index|
25
+ ValueAdapter.to_neo(Bolt::Structure.value(value, index), elem)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def ruby_value(value, index)
32
+ ValueAdapter.to_ruby(Bolt::Structure.value(value, index))
33
+ end
34
+
35
+ def size
36
+ @size ||= method(:to_ruby_value).arity
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module TimeWithZoneIdValue
8
+ CODE = :f
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(epoch_second_local, nsec, zone_id_string)
13
+ time = Time.at(epoch_second_local, nsec, :nsec).in_time_zone(TZInfo::Timezone.get(zone_id_string))
14
+ time - time.utc_offset
15
+ end
16
+
17
+ def to_neo_values(time)
18
+ [time.to_i + time.utc_offset, time.nsec, time.time_zone.tzinfo.identifier]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Internal
6
+ module Value
7
+ module TimeWithZoneOffsetValue
8
+ CODE = :F
9
+ extend StructureValue
10
+
11
+ class << self
12
+ def to_ruby_value(epoch_second_local, nsec, offset)
13
+ time = Time.at(epoch_second_local, nsec, :nsec).utc
14
+ Time.new(time.year, time.month, time.mday, time.hour, time.min, time.sec + Rational(nsec, 1_000_000_000),
15
+ offset)
16
+ # In ruby 2.6.x
17
+ # Time.at(sec, nsec, :nsec, tz: offset)
18
+ end
19
+
20
+ def to_neo_values(time)
21
+ [time.to_i + time.utc_offset, time.nsec, time.utc_offset]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end