Class: Neo4j::Driver::PackStream::Packer

Inherits:
Object
  • Object
show all
Includes:
Markers
Defined in:
lib/neo4j/driver/packstream/packer.rb

Overview

PackStream Packer - serializes Ruby objects to PackStream binary format Based on https://neo4j.com/docs/bolt/current/packstream/

Constant Summary

Constants included from Markers

Markers::BYTES_16, Markers::BYTES_32, Markers::BYTES_8, Markers::FALSE, Markers::FLOAT_64, Markers::INT_16, Markers::INT_32, Markers::INT_64, Markers::INT_8, Markers::LIST_16, Markers::LIST_32, Markers::LIST_8, Markers::MAP_16, Markers::MAP_32, Markers::MAP_8, Markers::NULL, Markers::STRING_16, Markers::STRING_32, Markers::STRING_8, Markers::STRUCT_16, Markers::STRUCT_8, Markers::TINY_LIST, Markers::TINY_MAP, Markers::TINY_STRING, Markers::TINY_STRUCT, Markers::TRUE, Markers::UUID

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocol) ⇒ Packer

Returns a new instance of Packer.



17
18
19
20
21
# File 'lib/neo4j/driver/packstream/packer.rb', line 17

def initialize(protocol)
  @buffer = String.new(encoding: Encoding::BINARY)
  @use_utc_datetime = false
  @protocol = protocol
end

Instance Attribute Details

#use_utc_datetimeObject

When true, datetimes are packed as the UTC-seconds Bolt 5.0+ structures (0x49 / 0x69) instead of the legacy local-seconds variants (0x46 / 0x66). Connection sets this after a successful handshake negotiates Bolt 5.0+; ignored on 4.x.



15
16
17
# File 'lib/neo4j/driver/packstream/packer.rb', line 15

def use_utc_datetime
  @use_utc_datetime
end

Instance Method Details

#bytesObject



89
90
91
# File 'lib/neo4j/driver/packstream/packer.rb', line 89

def bytes
  @buffer
end

#pack(value) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/neo4j/driver/packstream/packer.rb', line 23

def pack(value)
  case value
  when nil
    pack_null
  when true, false
    pack_boolean(value)
  when Integer
    pack_integer(value)
  when Float
    pack_float(value)
  when String
    # Pack binary strings as BYTES, text strings as STRING
    value.encoding == Encoding::BINARY ? pack_bytes(value) : pack_string(value)
  when Symbol
    pack_string(value.to_s)
  when Hash
    # Check Hash before Enumerable since Hash is also Enumerable
    pack_map(value)
  when Types::Node, Types::Relationship, Types::Path, Types::UnsupportedType
    # Graph types are not valid query parameters; neither is an
    # UnsupportedType (a value the driver couldn't materialise — it
    # must not be sent back to the server). Reject before the Enumerable
    # branch since Path includes Enumerable.
    Exceptions::ClientException.unable_to_convert(value)
  when Array, Set, Range
    # Known sized collections — pack_list uses #size, which is O(1) here.
    pack_list(value)
  when Enumerable
    # Generic Enumerable (lazy enumerators, custom collections) — materialise
    # so #size is well-defined.
    pack_list(value.to_a)
  when ::DateTime, ::Time
    # Check DateTime before Date — DateTime < Date in Ruby, so the
    # Date branch would match first and pack away the time component.
    pack_datetime(value)
  when ::Date
    # Pack Ruby Date as Neo4j Date structure
    pack_date(value)
  when Types::LocalDateTime
    pack_local_datetime(value)
  when Types::LocalTime
    pack_local_time(value)
  when Types::OffsetTime
    pack_offset_time(value)
  when Types::Point
    pack_point(value)
  when Types::Duration
    pack_duration(value)
  when Types::UUID
    # A PackStream V2 type: only the negotiated protocol decides whether
    # it can be sent — V61 packs it, every earlier version rejects it.
    @protocol.pack_uuid(self, value)
  else
    Exceptions::ClientException.unable_to_convert(value)
  end
  self
end

#pack_message(structure) ⇒ Object

Serialise a Bolt protocol message (a PackStream::Structure) onto the buffer. Distinct from #pack so the user-value path doesn't carry knowledge of the wire-level Structure type.



84
85
86
87
# File 'lib/neo4j/driver/packstream/packer.rb', line 84

def pack_message(structure)
  pack_structure(structure)
  self
end

#pack_uuid_value(value) ⇒ Object

PackStream V2 UUID (Bolt 6.1+): marker 0xE0 + 16 raw bytes. Called by Protocol::V61#pack_uuid — every earlier protocol rejects a UUID instead, so this is only reached once 6.1 is negotiated.



101
102
103
104
# File 'lib/neo4j/driver/packstream/packer.rb', line 101

def pack_uuid_value(value)
  @buffer << [UUID].pack('C')
  @buffer << [value.to_s.delete('-')].pack('H*')
end

#resetObject



93
94
95
96
# File 'lib/neo4j/driver/packstream/packer.rb', line 93

def reset
  @buffer.clear
  self
end