Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5 protocol implemented #218

Draft
wants to merge 1 commit into
base: 5.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions ruby/neo4j/driver/internal/messaging/v5/bolt_protocol_v5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Neo4j::Driver
module Internal
module Messaging
module V5
# Definition of the Bolt Protocol 4.4
class BoltProtocolV5 < V44::BoltProtocolV44
VERSION = BoltProtocolVersion.new(5,0)
INSTANCE = new

def create_message_format
MessageFormatV5.new
end

def include_date_time_utc_patch_in_hello
false
end
end
end
end
end
end
18 changes: 18 additions & 0 deletions ruby/neo4j/driver/internal/messaging/v5/message_format_v5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Neo4j::Driver
module Internal
module Messaging
module V5
# Bolt message format v4.4
class MessageFormatV5
def new_writer(output)
MessageWriterV5.new(output)
end

def new_reader(input)
MessageReaderV5.new(input)
end
end
end
end
end
end
13 changes: 13 additions & 0 deletions ruby/neo4j/driver/internal/messaging/v5/message_reader_v5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Neo4j::Driver
module Internal
module Messaging
module V5
class MessageReaderV5 < Common::CommonMessageReader
def initialize(input)
super(ValueUnpackerV5.new(input))
end
end
end
end
end
end
33 changes: 33 additions & 0 deletions ruby/neo4j/driver/internal/messaging/v5/message_writer_v5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Neo4j::Driver
module Internal
module Messaging
module V5
class MessageWriterV5 < AbstractMessageWriter
def initialize(input)
super(Common::CommonValuePacker.new(output), build_encoders)
end

private

def build_encoders
result[Request::HelloMessage::SIGNATURE] = Encode::HelloMessageEncoder.new
result[Request::GoodbyeMessage::SIGNATURE] = Encode::GoodbyeMessageEncoder.new
result[Request::RunWithMetadataMessage::SIGNATURE] = Encode::RunWithMetadataMessageEncoder.new
result[Request::RouteMessage::SIGNATURE] = Encode::RouteV44MessageEncoder.new

result[Request::DiscardMessage::SIGNATURE] = Encode::DiscardMessageEncoder.new
result[Request::PullMessage::SIGNATURE] = Encode::PullMessageEncoder.new

result[Request::BeginMessage::SIGNATURE] = Encode::BeginMessageEncoder.new
result[Request::CommitMessage::SIGNATURE] = Encode::CommitMessageEncoder.new
result[Request::RollbackMessage::SIGNATURE] = Encode::RollbackMessageEncoder.new

result[Request::ResetMessage::SIGNATURE] = Encode::ResetMessageEncoder.new

result
end
end
end
end
end
end
113 changes: 113 additions & 0 deletions ruby/neo4j/driver/internal/messaging/v5/value_unpacker_v5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module Neo4j::Driver
module Internal
module Messaging
module V5
class ValueUnpackerV5 < Common::CommonValueUnpacker
NODE_FIELDS = 4
RELATIONSHIP_FIELDS = 8

def initialize(input)
super(input, true)
end

def node_fiunpack_nodeelds
urn = unpacker.unpack_long

num_labels = unpacker.unpack_list_header
labels = []

num_labels.times do
labels << unpacker.unpack_string
end

num_props = unpacker.unpack_map_header
props = {}

num_props.times do
props[unpacker.unpack_string] = unpack
end

element_id = unpacker.unpack_string

Internal::InternalNode.new(urn, element_id, labels, props)
end

def unpack_path
# List of unique nodes
uniq_nodes = Internal::InternalNode.new(unpacker.unpack_list_header)

uniq_nodes.times do |i|
ensure_correct_struct_size(:NODE, NODE_FIELDS, unpacker.unpack_struct_header)
ensure_correct_struct_signature("NODE", NODE, unpacker.unpack_struct_signature)
uniq_nodes[i] = unpack_node
end

# List of unique relationships, without start/end information
uniq_rels = Internal::InternalRelationship.new(unpacker.unpack_list_header)

uniq_rels.times do |i|
ensure_correct_struct_size(:RELATIONSHIP, 4, unpacker.unpack_struct_header)
ensure_correct_struct_signature("UNBOUND_RELATIONSHIP", UNBOUND_RELATIONSHIP, unpacker.unpack_struct_signature)
id = unpacker.unpack_long
rel_type = unpacker.unpack_string
props = unpack_map
element_id = unpacker.unpack_string
uniq_rels[i] = Internal::InternalRelationship.new(id, element_id, -1.to_s, -1, -1.to_s, rel_type, props)
end

# Path sequence
length = unpacker.unpack_list_header

# Knowing the sequence length, we can create the arrays that will represent the nodes, rels and segments in
# their "path order
segments = length / 2
nodes = segments.length = 1
rels = segments.length

prev_node = uniq_nodes[0], next_node # Start node is always 0, and isn't encoded in the sequence
nodes[0] = prev_node

segments.length.times do |i|
rel_idx = unpacker.unpack_long
next_node = uniq_nodes[unpacker.unpack_long]
# Negative rel index means this rel was traversed "inversed" from its direction

if rel_idx < 0
rel = uniq_rels[(-rel_idx) - 1] # -1 because rel idx are 1-indexed
set_start_and_end(rel, next_node, prev_node)
else
rel = uniq_rels[rel_idx - 1]
set_start_and_end(rel, prev_node, next_node)
end

nodes[i + 1] = next_node
rels[i] = rel
segments[i] = Internal::InternalPath::Segment.new(prev_node, rel, next_node)
prev_node = next_node
end

Internal::InternalPath.new(segments, nodes, rels)
end

private def set_start_and_end(rel, start, finish)
rel.set_start_and_end(start.id, start.element_id, finish.id, finish.element_id)
end

def unpack_relationship
urn = unpacker.unpack_long
start_urn = unpacker.unpack_long
end_urn = unpacker.unpack_long
rel_type = unpacker.unpack_string
props = unpack_map
element_id = unpacker.unpack_string
start_element_id = unpacker.unpack_string
end_element_id = unpacker.unpack_string

adapted = Internal::InternalRelationship.new(urn, element_id, start_urn, start_element_id, end_urn, end_element_id, rel_type, props)
Internal::Value::RelationshipValue.new(adapted)
end
end
end
end
end
end