neospace 0.0.1 → 1.7.0

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