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.
- checksums.yaml +4 -4
- data/LICENSE.txt +21 -0
- data/README.md +88 -0
- data/ffi/bolt/address.rb +11 -0
- data/ffi/bolt/address_resolver.rb +12 -0
- data/ffi/bolt/address_set.rb +9 -0
- data/ffi/bolt/auth.rb +10 -0
- data/ffi/bolt/auto_releasable.rb +22 -0
- data/ffi/bolt/boolean.rb +9 -0
- data/ffi/bolt/bytes.rb +10 -0
- data/ffi/bolt/config.rb +45 -0
- data/ffi/bolt/connection.rb +44 -0
- data/ffi/bolt/connector.rb +17 -0
- data/ffi/bolt/dictionary.rb +15 -0
- data/ffi/bolt/error.rb +74 -0
- data/ffi/bolt/float.rb +9 -0
- data/ffi/bolt/integer.rb +9 -0
- data/ffi/bolt/library.rb +12 -0
- data/ffi/bolt/lifecycle.rb +9 -0
- data/ffi/bolt/list.rb +10 -0
- data/ffi/bolt/log.rb +16 -0
- data/ffi/bolt/socket_options.rb +14 -0
- data/ffi/bolt/status.rb +25 -0
- data/ffi/bolt/string.rb +9 -0
- data/ffi/bolt/structure.rb +10 -0
- data/ffi/bolt/value.rb +35 -0
- data/ffi/neo4j/driver.rb +60 -0
- data/ffi/neo4j/driver/access_mode.rb +10 -0
- data/ffi/neo4j/driver/auth_tokens.rb +18 -0
- data/ffi/neo4j/driver/config.rb +40 -0
- data/ffi/neo4j/driver/graph_database.rb +52 -0
- data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +19 -0
- data/ffi/neo4j/driver/internal/async/direct_connection.rb +106 -0
- data/ffi/neo4j/driver/internal/bolt_server_address.rb +18 -0
- data/ffi/neo4j/driver/internal/bookmarks_holder.rb +30 -0
- data/ffi/neo4j/driver/internal/direct_connection_provider.rb +28 -0
- data/ffi/neo4j/driver/internal/driver_factory.rb +125 -0
- data/ffi/neo4j/driver/internal/error_handling.rb +108 -0
- data/ffi/neo4j/driver/internal/explicit_transaction.rb +146 -0
- data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +105 -0
- data/ffi/neo4j/driver/internal/handlers/response_handler.rb +49 -0
- data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +32 -0
- data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +32 -0
- data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +23 -0
- data/ffi/neo4j/driver/internal/internal_driver.rb +45 -0
- data/ffi/neo4j/driver/internal/internal_logger.rb +32 -0
- data/ffi/neo4j/driver/internal/internal_record.rb +26 -0
- data/ffi/neo4j/driver/internal/internal_resolver.rb +31 -0
- data/ffi/neo4j/driver/internal/internal_statement_result.rb +52 -0
- data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +24 -0
- data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +59 -0
- data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +16 -0
- data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +63 -0
- data/ffi/neo4j/driver/internal/network_session.rb +129 -0
- data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +80 -0
- data/ffi/neo4j/driver/internal/session_factory_impl.rb +28 -0
- data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +67 -0
- data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +19 -0
- data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +23 -0
- data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +15 -0
- data/ffi/neo4j/driver/internal/value/base_time_value.rb +22 -0
- data/ffi/neo4j/driver/internal/value/date_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/duration_value.rb +27 -0
- data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/local_time_value.rb +19 -0
- data/ffi/neo4j/driver/internal/value/node_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/offset_time_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/path_value.rb +41 -0
- data/ffi/neo4j/driver/internal/value/point2_d_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/point3_d_value.rb +24 -0
- data/ffi/neo4j/driver/internal/value/relationship_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/structure_value.rb +42 -0
- data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +25 -0
- data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +28 -0
- data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +18 -0
- data/ffi/neo4j/driver/internal/value/value_adapter.rb +99 -0
- data/ffi/neo4j/driver/net/server_address.rb +13 -0
- data/ffi/neo4j/driver/statement.rb +15 -0
- data/ffi/neo4j/driver/summary/statement_type.rb +14 -0
- data/ffi/neo4j/driver/types/entity.rb +21 -0
- data/ffi/neo4j/driver/types/node.rb +16 -0
- data/ffi/neo4j/driver/types/path.rb +35 -0
- data/ffi/neo4j/driver/types/relationship.rb +19 -0
- data/lib/loader.rb +18 -0
- data/lib/neo4j/driver/auto_closable.rb +32 -0
- data/lib/neo4j/driver/exceptions/authentication_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/client_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/database_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/illegal_state_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/neo4j_exception.rb +23 -0
- data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +33 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/security_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/session_expired_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/transient_exception.rb +10 -0
- data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +10 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +46 -0
- data/lib/neo4j/driver/internal/ruby_signature.rb +18 -0
- data/lib/neo4j/driver/internal/validator.rb +28 -0
- data/lib/neo4j/driver/types/bytes.rb +10 -0
- data/lib/neo4j/driver/types/local_date_time.rb +20 -0
- data/lib/neo4j/driver/types/local_time.rb +19 -0
- data/lib/neo4j/driver/types/offset_time.rb +19 -0
- data/lib/neo4j/driver/types/point.rb +39 -0
- data/lib/neo4j/driver/types/time.rb +43 -0
- data/lib/neo4j/driver/version.rb +7 -0
- data/lib/neo4j_ruby_driver.rb +20 -0
- metadata +314 -12
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Value
|
|
7
|
+
module UnboundRelationshipValue
|
|
8
|
+
CODE = :r
|
|
9
|
+
extend StructureValue
|
|
10
|
+
|
|
11
|
+
def self.to_ruby_value(id, type, properties)
|
|
12
|
+
Types::Relationship.new(id, nil, nil, type, properties)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Internal
|
|
6
|
+
module Value
|
|
7
|
+
module ValueAdapter
|
|
8
|
+
class << self
|
|
9
|
+
def to_ruby(value)
|
|
10
|
+
case Bolt::Value.type(value)
|
|
11
|
+
when :bolt_null
|
|
12
|
+
nil
|
|
13
|
+
when :bolt_boolean
|
|
14
|
+
Bolt::Boolean.get(value) == 1
|
|
15
|
+
when :bolt_integer
|
|
16
|
+
Bolt::Integer.get(value)
|
|
17
|
+
when :bolt_float
|
|
18
|
+
Bolt::Float.get(value)
|
|
19
|
+
when :bolt_bytes
|
|
20
|
+
Types::Bytes.new(Array.new(Bolt::Value.size(value)) { |i| Bolt::Bytes.get(value, i) }.pack('C*'))
|
|
21
|
+
when :bolt_string
|
|
22
|
+
Bolt::String.get(value).read_string(Bolt::Value.size(value)).force_encoding(Encoding::UTF_8)
|
|
23
|
+
when :bolt_dictionary
|
|
24
|
+
Array.new(Bolt::Value.size(value)) do |i|
|
|
25
|
+
[to_ruby(Bolt::Dictionary.key(value, i)).to_sym, to_ruby(Bolt::Dictionary.value(value, i))]
|
|
26
|
+
end.to_h
|
|
27
|
+
when :bolt_list
|
|
28
|
+
Array.new(Bolt::Value.size(value)) { |i| to_ruby(Bolt::List.value(value, i)) }
|
|
29
|
+
when :bolt_structure
|
|
30
|
+
StructureValue.to_ruby(value)
|
|
31
|
+
else
|
|
32
|
+
raise Exception, 'unsupported neo4j type'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def to_neo(value, object)
|
|
37
|
+
case object
|
|
38
|
+
when nil
|
|
39
|
+
Bolt::Value.format_as_null(value)
|
|
40
|
+
when TrueClass
|
|
41
|
+
Bolt::Value.format_as_boolean(value, 1)
|
|
42
|
+
when FalseClass
|
|
43
|
+
Bolt::Value.format_as_boolean(value, 0)
|
|
44
|
+
when Integer
|
|
45
|
+
Bolt::Value.format_as_integer(value, object)
|
|
46
|
+
when Float
|
|
47
|
+
Bolt::Value.format_as_float(value, object)
|
|
48
|
+
when Types::Bytes
|
|
49
|
+
Bolt::Value.format_as_bytes(value, object, object.size)
|
|
50
|
+
when String
|
|
51
|
+
object = object.encode(Encoding::UTF_8) unless object.encoding == Encoding::UTF_8
|
|
52
|
+
Bolt::Value.format_as_string(value, object, object.bytesize)
|
|
53
|
+
when Hash
|
|
54
|
+
Bolt::Value.format_as_dictionary(value, object.size)
|
|
55
|
+
object.each_with_index do |(key, elem), index|
|
|
56
|
+
key = key.to_s
|
|
57
|
+
Bolt::Dictionary.set_key(value, index, key, key.bytesize)
|
|
58
|
+
to_neo(Bolt::Dictionary.value(value, index), elem)
|
|
59
|
+
end
|
|
60
|
+
when Types::Path
|
|
61
|
+
Exceptions::ClientException.unable_to_convert(object)
|
|
62
|
+
when Enumerable
|
|
63
|
+
object = object.to_a
|
|
64
|
+
Bolt::Value.format_as_list(value, object.size)
|
|
65
|
+
object.each_with_index { |elem, index| to_neo(Bolt::List.value(value, index), elem) }
|
|
66
|
+
when Date
|
|
67
|
+
DateValue.to_neo(value, object)
|
|
68
|
+
when ActiveSupport::Duration
|
|
69
|
+
DurationValue.to_neo(value, object)
|
|
70
|
+
when Neo4j::Driver::Types::Point
|
|
71
|
+
case object.coordinates.size
|
|
72
|
+
when 2
|
|
73
|
+
Point2DValue
|
|
74
|
+
when 3
|
|
75
|
+
Point3DValue
|
|
76
|
+
else
|
|
77
|
+
raise Exception
|
|
78
|
+
end&.to_neo(value, object)
|
|
79
|
+
when Types::OffsetTime
|
|
80
|
+
OffsetTimeValue.to_neo(value, object)
|
|
81
|
+
when Types::LocalTime
|
|
82
|
+
LocalTimeValue.to_neo(value, object)
|
|
83
|
+
when Types::LocalDateTime
|
|
84
|
+
LocalDateTimeValue.to_neo(value, object)
|
|
85
|
+
when ActiveSupport::TimeWithZone
|
|
86
|
+
TimeWithZoneIdValue.to_neo(value, object)
|
|
87
|
+
when Time
|
|
88
|
+
TimeWithZoneOffsetValue.to_neo(value, object)
|
|
89
|
+
else
|
|
90
|
+
Exceptions::ClientException.unable_to_convert(object)
|
|
91
|
+
end
|
|
92
|
+
value
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
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 = nil)
|
|
9
|
+
Internal::Validator.require_hash_parameters!(parameters)
|
|
10
|
+
@text = text
|
|
11
|
+
@parameters = parameters || {}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
|
|
15
|
+
def ==(other)
|
|
16
|
+
self.class == other.class && id == other.id
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
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.to_sym
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/loader.rb
ADDED
|
@@ -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,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Exceptions
|
|
6
|
+
class ClientException < Neo4jException
|
|
7
|
+
class << self
|
|
8
|
+
def unable_to_convert(object)
|
|
9
|
+
raise self, "Unable to convert #{object.class.name} to Neo4j Value."
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Exceptions
|
|
6
|
+
class Neo4jException < RuntimeError
|
|
7
|
+
attr_reader :code, :cause, :suppressed
|
|
8
|
+
|
|
9
|
+
def initialize(*args)
|
|
10
|
+
@code = args.shift if args.count > 1
|
|
11
|
+
message = args.shift
|
|
12
|
+
@cause = args.shift
|
|
13
|
+
@suppressed = args.shift
|
|
14
|
+
super(message)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_suppressed(exception)
|
|
18
|
+
(@suppressed ||= []) << exception
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
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
|