Class: Neo4j::Driver::Bolt::Protocol::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/neo4j/driver/bolt/protocol/base.rb

Overview

Base of the per-minor protocol class hierarchy. Mirrors Java's BoltProtocolVxY family in neo4j-bolt-connection-java — each minor version is its own subclass and only overrides what changed at that version, instead of carrying a swarm of version >= V5_X checks inside one big class.

Direct Known Subclasses

V3, V4

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, version) ⇒ Base

Returns a new instance of Base.



15
16
17
18
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 15

def initialize(connection, version)
  @connection = connection
  @version = version
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



13
14
15
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 13

def connection
  @connection
end

#versionObject (readonly)

Returns the value of attribute version.



13
14
15
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 13

def version
  @version
end

Instance Method Details

#build_begin(extra, notification_config: nil) ⇒ Object



91
92
93
94
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 91

def build_begin(extra, notification_config: nil)
  enforce_impersonation_support!(extra[:imp_user])
  Message.begin_transaction(strip_db(extra).merge(notification_config_extra(notification_config).compact))
end

#build_discard(extra) ⇒ Object

4.0+ DISCARD carries {n, qid}. V3 overrides to DISCARD_ALL.



103
104
105
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 103

def build_discard(extra)
  Message.discard(extra)
end

#build_hello_message(user_agent:, auth:, routing: nil, notification_config: nil) ⇒ Object

Top-level HELLO builder. The shape is fixed (one map argument); subclasses override hello_extra to change which keys it carries at their version. notification_config (the driver's NotificationsConfig, a {minimum_severity:, disabled_categories:} hash or nil) only lands on the wire from V52 on — older versions return an empty map from notification_config_extra.



26
27
28
29
30
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 26

def build_hello_message(user_agent:, auth:, routing: nil, notification_config: nil)
  extra = hello_extra(user_agent:, auth:, routing:)
          .merge(notification_config_extra(notification_config))
  PackStream::Structure.new(Message::HELLO, [extra.compact])
end

#build_logon_message(_auth) ⇒ Object

Hook for V51+ (HELLO/LOGON split): the LOGON message the connection pipelines right after HELLO. nil here — older versions carry auth in the HELLO map and send no separate LOGON.



48
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 48

def build_logon_message(_auth) = nil

#build_pull(extra) ⇒ Object

4.0+ PULL carries {n, qid}. V3 overrides to the parameterless PULL_ALL.



98
99
100
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 98

def build_pull(extra)
  Message.pull(extra)
end

#build_run(query, parameters, extra, notification_config: nil) ⇒ Object

notification_config is the SESSION's NotificationsConfig (the driver's rides on HELLO). It reaches the wire only on V5_2+, where notification_config_extra emits the keys; .compact there drops an unset severity while keeping an explicit disabled_categories: [].



85
86
87
88
89
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 85

def build_run(query, parameters, extra, notification_config: nil)
  enforce_impersonation_support!(extra[:imp_user])
  Message.run(query, parameters,
              strip_db(extra).merge(notification_config_extra(notification_config).compact))
end

#build_telemetry(api) ⇒ Object



107
108
109
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 107

def build_telemetry(api)
  Message.telemetry(api)
end

#configure_packer(_packer) ⇒ Object

Hook for V5+: lets the protocol flip the packer's UTC datetime flag (0x49 / 0x69 vs legacy 0x46 / 0x66).



52
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 52

def configure_packer(_packer); end

#customize_hydration(_unpacker) ⇒ Object

Hook for per-version unpacker customisation — re-registering handlers for messages whose shape changed at this version (V57 FAILURE) or adding handlers for new struct types (V6 VECTOR / UNSUPPORTED). Called after Connection registers the common ones, so an override here wins.



59
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 59

def customize_hydration(_unpacker); end

#enforce_impersonation_support!(imp_user) ⇒ Object

Fail fast when a caller asks to impersonate over a protocol that can't carry imp_user (Bolt < 4.4) — otherwise the field is silently dropped and the query runs as the authenticated user. Matches Java, which raises ClientException here. Public so Connection#route can enforce the same rule on the discovery path (a routed session impersonating against a 4.3 cluster must fail before sending ROUTE, not silently lose imp_user).



128
129
130
131
132
133
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 128

def enforce_impersonation_support!(imp_user)
  return if imp_user.nil? || supports_impersonation?

  raise Exceptions::ClientException,
        "Impersonation (impersonated_user) is not supported on Bolt #{version}; requires Bolt 4.4+"
end

#hello_extra(user_agent:, auth:, routing:) ⇒ Object

The HELLO map. Auth lives inside HELLO through Bolt 5.0; routing is the routing context (nil for a direct bolt:// connection, compacted away by build_hello_message). V51 overrides this to drop **auth once auth splits out into a separate LOGON message.



37
38
39
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 37

def hello_extra(user_agent:, auth:, routing:)
  { user_agent:, routing:, **auth }
end

#notification_config_extra(_notification_config) ⇒ Object

Notification-filtering keys for the HELLO map. Empty until V52, the first version whose server honours them (V52 overrides this).



43
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 43

def notification_config_extra(_notification_config) = {}

#pack_uuid(_packer, value) ⇒ Object

PackStream V2 (Bolt 6.1+) UUID codec. UUID is a version-specific type: only Protocol::V61 packs/unpacks it — every earlier version rejects it. Packing raises a ClientException naming the type; unpacking treats the 0xE0 marker as unknown.



65
66
67
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 65

def pack_uuid(_packer, value)
  Exceptions::ClientException.unable_to_convert(value)
end

#supports_impersonation?Boolean

Impersonation (imp_user on RUN/BEGIN/ROUTE) arrived with Bolt 4.4; V44 flips this to true.

Returns:

  • (Boolean)


119
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 119

def supports_impersonation? = false

#supports_multiple_databases?Boolean

Returns:

  • (Boolean)


112
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 112

def supports_multiple_databases? = false

#supports_notification_filtering?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 113

def supports_notification_filtering? = false
# TELEMETRY (driver-API usage reporting) arrived with Bolt 5.4;
# V54 flips this to true.

#supports_re_auth?Boolean

Returns:

  • (Boolean)


111
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 111

def supports_re_auth? = false

#supports_telemetry?Boolean

TELEMETRY (driver-API usage reporting) arrived with Bolt 5.4; V54 flips this to true.

Returns:

  • (Boolean)


116
117
118
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 116

def supports_telemetry? = false
# Impersonation (imp_user on RUN/BEGIN/ROUTE) arrived with Bolt 4.4;
# V44 flips this to true.

#unpack_uuid(unpacker) ⇒ Object



69
70
71
# File 'lib/neo4j/driver/bolt/protocol/base.rb', line 69

def unpack_uuid(unpacker)
  unpacker.raise_unknown_marker(PackStream::Markers::UUID)
end