neo4j-ruby-driver 6.0.0.alpha.2 → 6.2.1.beta.1

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.
Files changed (346) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +113 -411
  3. data/{ruby → lib}/neo4j/driver/access_mode.rb +2 -1
  4. data/lib/neo4j/driver/auth_token_managers.rb +31 -0
  5. data/lib/neo4j/driver/auth_tokens.rb +41 -0
  6. data/lib/neo4j/driver/auto_commit_retries_mode.rb +18 -0
  7. data/lib/neo4j/driver/bolt/bolt_version.rb +67 -0
  8. data/lib/neo4j/driver/bolt/connection.rb +1054 -0
  9. data/lib/neo4j/driver/bolt/handshake.rb +232 -0
  10. data/lib/neo4j/driver/bolt/message/failure.rb +139 -0
  11. data/lib/neo4j/driver/bolt/message/ignored.rb +27 -0
  12. data/lib/neo4j/driver/bolt/message/record.rb +30 -0
  13. data/lib/neo4j/driver/bolt/message/success.rb +34 -0
  14. data/lib/neo4j/driver/bolt/message.rb +112 -0
  15. data/lib/neo4j/driver/bolt/pool.rb +255 -0
  16. data/lib/neo4j/driver/bolt/protocol/base.rb +146 -0
  17. data/lib/neo4j/driver/bolt/protocol/v3.rb +43 -0
  18. data/lib/neo4j/driver/bolt/protocol/v4.rb +24 -0
  19. data/lib/neo4j/driver/bolt/protocol/v43.rb +28 -0
  20. data/lib/neo4j/driver/bolt/protocol/v44.rb +23 -0
  21. data/lib/neo4j/driver/bolt/protocol/v5.rb +27 -0
  22. data/lib/neo4j/driver/bolt/protocol/v51.rb +24 -0
  23. data/lib/neo4j/driver/bolt/protocol/v52.rb +28 -0
  24. data/lib/neo4j/driver/bolt/protocol/v53.rb +27 -0
  25. data/lib/neo4j/driver/bolt/protocol/v54.rb +14 -0
  26. data/lib/neo4j/driver/bolt/protocol/v55.rb +17 -0
  27. data/lib/neo4j/driver/bolt/protocol/v56.rb +14 -0
  28. data/lib/neo4j/driver/bolt/protocol/v57.rb +31 -0
  29. data/lib/neo4j/driver/bolt/protocol/v58.rb +15 -0
  30. data/lib/neo4j/driver/bolt/protocol/v6.rb +43 -0
  31. data/lib/neo4j/driver/bolt/protocol/v61.rb +21 -0
  32. data/lib/neo4j/driver/bolt/protocol_version_handler.rb +39 -0
  33. data/lib/neo4j/driver/bolt/record_buffer.rb +136 -0
  34. data/lib/neo4j/driver/bolt/stream_handler.rb +53 -0
  35. data/lib/neo4j/driver/bolt/tls_config.rb +129 -0
  36. data/lib/neo4j/driver/bolt/wire.rb +321 -0
  37. data/lib/neo4j/driver/bookmark.rb +15 -0
  38. data/lib/neo4j/driver/bookmark_managers.rb +39 -0
  39. data/lib/neo4j/driver/client_certificate.rb +19 -0
  40. data/lib/neo4j/driver/client_certificate_manager.rb +37 -0
  41. data/lib/neo4j/driver/client_certificate_managers.rb +15 -0
  42. data/lib/neo4j/driver/client_certificates.rb +14 -0
  43. data/lib/neo4j/driver/direct/connection_provider.rb +258 -0
  44. data/lib/neo4j/driver/driver.rb +268 -0
  45. data/lib/neo4j/driver/eager_result.rb +10 -0
  46. data/lib/neo4j/driver/exceptions/neo4j_exception.rb +16 -7
  47. data/lib/neo4j/driver/exceptions/protocol_exception.rb +0 -5
  48. data/lib/neo4j/driver/exceptions/security_retryable_exception.rb +14 -0
  49. data/lib/neo4j/driver/exceptions/transaction_terminated_exception.rb +13 -0
  50. data/lib/neo4j/driver/graph_database.rb +29 -0
  51. data/lib/neo4j/driver/internal/clock.rb +20 -0
  52. data/lib/neo4j/driver/internal/clock_adapter.rb +21 -0
  53. data/lib/neo4j/driver/internal/default_bookmark_manager.rb +54 -0
  54. data/lib/neo4j/driver/internal/deprecator.rb +9 -5
  55. data/lib/neo4j/driver/internal/driver_factory.rb +128 -0
  56. data/lib/neo4j/driver/internal/duration_normalizer.rb +14 -41
  57. data/lib/neo4j/driver/internal/extras.rb +23 -0
  58. data/lib/neo4j/driver/internal/home_db_cache.rb +57 -0
  59. data/lib/neo4j/driver/internal/internal_auth_token_manager.rb +37 -0
  60. data/lib/neo4j/driver/internal/metrics.rb +31 -0
  61. data/lib/neo4j/driver/internal/security/static_auth_token_manager.rb +25 -0
  62. data/lib/neo4j/driver/internal/validator.rb +10 -0
  63. data/lib/neo4j/driver/net.rb +29 -0
  64. data/lib/neo4j/driver/packstream/markers.rb +49 -0
  65. data/lib/neo4j/driver/packstream/packer.rb +333 -0
  66. data/lib/neo4j/driver/packstream/structure.rb +27 -0
  67. data/lib/neo4j/driver/packstream/unpacker.rb +168 -0
  68. data/lib/neo4j/driver/record.rb +49 -0
  69. data/lib/neo4j/driver/result.rb +282 -0
  70. data/lib/neo4j/driver/routing/load_balancer.rb +690 -0
  71. data/lib/neo4j/driver/routing/routed_connection.rb +132 -0
  72. data/lib/neo4j/driver/routing/routing_table.rb +127 -0
  73. data/lib/neo4j/driver/routing/server_address.rb +25 -0
  74. data/lib/neo4j/driver/routing_control.rb +13 -0
  75. data/lib/neo4j/driver/session.rb +575 -0
  76. data/lib/neo4j/driver/summary/database_info.rb +25 -0
  77. data/lib/neo4j/driver/summary/gql_notification.rb +38 -0
  78. data/lib/neo4j/driver/summary/gql_status_object.rb +35 -0
  79. data/lib/neo4j/driver/summary/notification.rb +46 -0
  80. data/lib/neo4j/driver/summary/plan.rb +23 -0
  81. data/lib/neo4j/driver/summary/profile.rb +28 -0
  82. data/lib/neo4j/driver/summary/query.rb +19 -0
  83. data/lib/neo4j/driver/summary/query_type.rb +5 -1
  84. data/lib/neo4j/driver/summary/result_summary.rb +213 -0
  85. data/lib/neo4j/driver/summary/server_info.rb +33 -0
  86. data/lib/neo4j/driver/summary/summary_counters.rb +72 -0
  87. data/lib/neo4j/driver/transaction.rb +341 -0
  88. data/lib/neo4j/driver/types/duration.rb +76 -0
  89. data/lib/neo4j/driver/types/local_date_time.rb +52 -8
  90. data/lib/neo4j/driver/types/local_time.rb +42 -7
  91. data/lib/neo4j/driver/types/node.rb +27 -0
  92. data/lib/neo4j/driver/types/offset_time.rb +71 -7
  93. data/lib/neo4j/driver/types/path.rb +68 -0
  94. data/lib/neo4j/driver/types/point.rb +38 -18
  95. data/lib/neo4j/driver/types/relationship.rb +41 -0
  96. data/lib/neo4j/driver/types/temporal_value.rb +43 -0
  97. data/lib/neo4j/driver/types/unbound_relationship.rb +29 -0
  98. data/lib/neo4j/driver/types/unresolvable_zoned_date_time.rb +38 -0
  99. data/lib/neo4j/driver/types/unsupported_type.rb +25 -0
  100. data/lib/neo4j/driver/types/uuid.rb +29 -0
  101. data/{ruby → lib}/neo4j/driver/version.rb +1 -1
  102. data/lib/neo4j/driver.rb +16 -0
  103. data/lib/neo4j-ruby-driver_loader.rb +34 -20
  104. metadata +132 -390
  105. data/lib/neo4j/driver/internal/bolt_server_address.rb +0 -97
  106. data/lib/neo4j/driver/synchronizable.rb +0 -23
  107. data/lib/neo4j/driver/types/time.rb +0 -45
  108. data/ruby/neo4j/driver/auth_tokens.rb +0 -34
  109. data/ruby/neo4j/driver/bookmark.rb +0 -21
  110. data/ruby/neo4j/driver/config.rb +0 -89
  111. data/ruby/neo4j/driver/graph_database.rb +0 -78
  112. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +0 -51
  113. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +0 -22
  114. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +0 -31
  115. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +0 -32
  116. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +0 -83
  117. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +0 -22
  118. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +0 -30
  119. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +0 -83
  120. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +0 -27
  121. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +0 -113
  122. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +0 -57
  123. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +0 -26
  124. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +0 -19
  125. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +0 -36
  126. data/ruby/neo4j/driver/internal/async/connection/stream.rb +0 -12
  127. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +0 -16
  128. data/ruby/neo4j/driver/internal/async/connection_context.rb +0 -10
  129. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +0 -24
  130. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +0 -30
  131. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +0 -77
  132. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +0 -41
  133. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +0 -32
  134. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +0 -17
  135. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +0 -171
  136. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +0 -42
  137. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +0 -51
  138. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +0 -92
  139. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +0 -13
  140. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +0 -34
  141. data/ruby/neo4j/driver/internal/async/network_connection.rb +0 -194
  142. data/ruby/neo4j/driver/internal/async/network_session.rb +0 -150
  143. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +0 -110
  144. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +0 -39
  145. data/ruby/neo4j/driver/internal/async/pool/channel.rb +0 -66
  146. data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +0 -31
  147. data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +0 -135
  148. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +0 -156
  149. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +0 -87
  150. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +0 -52
  151. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +0 -21
  152. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +0 -34
  153. data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +0 -15
  154. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +0 -17
  155. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +0 -212
  156. data/ruby/neo4j/driver/internal/bookmark_holder.rb +0 -9
  157. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +0 -48
  158. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +0 -14
  159. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +0 -122
  160. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +0 -10
  161. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +0 -68
  162. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +0 -125
  163. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +0 -13
  164. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +0 -31
  165. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +0 -147
  166. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +0 -43
  167. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +0 -77
  168. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +0 -60
  169. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +0 -35
  170. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +0 -24
  171. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +0 -95
  172. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +0 -121
  173. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +0 -73
  174. data/ruby/neo4j/driver/internal/connection_settings.rb +0 -16
  175. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +0 -55
  176. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +0 -24
  177. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +0 -61
  178. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +0 -24
  179. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +0 -110
  180. data/ruby/neo4j/driver/internal/database_name_util.rb +0 -37
  181. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +0 -9
  182. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +0 -11
  183. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +0 -40
  184. data/ruby/neo4j/driver/internal/driver_factory.rb +0 -126
  185. data/ruby/neo4j/driver/internal/eager_result_value.rb +0 -5
  186. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +0 -20
  187. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +0 -30
  188. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +0 -23
  189. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +0 -65
  190. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +0 -34
  191. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +0 -199
  192. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +0 -16
  193. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +0 -29
  194. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +0 -32
  195. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +0 -169
  196. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +0 -298
  197. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +0 -20
  198. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +0 -34
  199. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +0 -25
  200. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +0 -21
  201. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +0 -79
  202. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +0 -38
  203. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +0 -34
  204. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +0 -20
  205. data/ruby/neo4j/driver/internal/impersonation_util.rb +0 -22
  206. data/ruby/neo4j/driver/internal/internal_bookmark.rb +0 -9
  207. data/ruby/neo4j/driver/internal/internal_database_name.rb +0 -9
  208. data/ruby/neo4j/driver/internal/internal_driver.rb +0 -83
  209. data/ruby/neo4j/driver/internal/internal_entity.rb +0 -21
  210. data/ruby/neo4j/driver/internal/internal_node.rb +0 -21
  211. data/ruby/neo4j/driver/internal/internal_pair.rb +0 -9
  212. data/ruby/neo4j/driver/internal/internal_path.rb +0 -35
  213. data/ruby/neo4j/driver/internal/internal_point2_d.rb +0 -9
  214. data/ruby/neo4j/driver/internal/internal_point3_d.rb +0 -6
  215. data/ruby/neo4j/driver/internal/internal_record.rb +0 -27
  216. data/ruby/neo4j/driver/internal/internal_relationship.rb +0 -27
  217. data/ruby/neo4j/driver/internal/internal_result.rb +0 -49
  218. data/ruby/neo4j/driver/internal/internal_session.rb +0 -91
  219. data/ruby/neo4j/driver/internal/internal_transaction.rb +0 -48
  220. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +0 -29
  221. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +0 -17
  222. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +0 -19
  223. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +0 -17
  224. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +0 -23
  225. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -32
  226. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +0 -48
  227. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +0 -51
  228. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +0 -33
  229. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +0 -104
  230. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +0 -256
  231. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +0 -15
  232. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +0 -14
  233. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +0 -14
  234. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +0 -15
  235. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +0 -14
  236. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +0 -15
  237. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +0 -16
  238. data/ruby/neo4j/driver/internal/messaging/encode/logoff_message_encoder.rb +0 -14
  239. data/ruby/neo4j/driver/internal/messaging/encode/logon_message_encoder.rb +0 -15
  240. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +0 -14
  241. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +0 -15
  242. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +0 -14
  243. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +0 -14
  244. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +0 -24
  245. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +0 -22
  246. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +0 -16
  247. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +0 -17
  248. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +0 -25
  249. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +0 -25
  250. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +0 -20
  251. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +0 -20
  252. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +0 -23
  253. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +0 -20
  254. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +0 -30
  255. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +0 -19
  256. data/ruby/neo4j/driver/internal/messaging/request/logoff_message.rb +0 -13
  257. data/ruby/neo4j/driver/internal/messaging/request/logon_message.rb +0 -13
  258. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +0 -17
  259. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +0 -26
  260. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +0 -23
  261. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +0 -22
  262. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +0 -32
  263. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +0 -20
  264. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +0 -28
  265. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +0 -23
  266. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +0 -49
  267. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +0 -24
  268. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +0 -40
  269. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +0 -29
  270. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +0 -33
  271. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +0 -34
  272. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -82
  273. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +0 -17
  274. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +0 -27
  275. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +0 -29
  276. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +0 -13
  277. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +0 -17
  278. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +0 -25
  279. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +0 -13
  280. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +0 -19
  281. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +0 -14
  282. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +0 -20
  283. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +0 -17
  284. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +0 -14
  285. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +0 -15
  286. data/ruby/neo4j/driver/internal/messaging/v5/bolt_protocol_v5.rb +0 -21
  287. data/ruby/neo4j/driver/internal/messaging/v5/message_format_v5.rb +0 -18
  288. data/ruby/neo4j/driver/internal/messaging/v5/value_unpacker_v5.rb +0 -17
  289. data/ruby/neo4j/driver/internal/messaging/v51/bolt_protocol_v51.rb +0 -40
  290. data/ruby/neo4j/driver/internal/messaging/v51/message_format_v51.rb +0 -14
  291. data/ruby/neo4j/driver/internal/messaging/v51/message_writer_v51.rb +0 -17
  292. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +0 -34
  293. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +0 -46
  294. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +0 -105
  295. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +0 -82
  296. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +0 -18
  297. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +0 -17
  298. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +0 -24
  299. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +0 -15
  300. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +0 -12
  301. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +0 -47
  302. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +0 -39
  303. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +0 -324
  304. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +0 -17
  305. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +0 -13
  306. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +0 -35
  307. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -150
  308. data/ruby/neo4j/driver/internal/revocation_strategy.rb +0 -19
  309. data/ruby/neo4j/driver/internal/scheme.rb +0 -32
  310. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +0 -15
  311. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +0 -48
  312. data/ruby/neo4j/driver/internal/security_setting.rb +0 -66
  313. data/ruby/neo4j/driver/internal/session_factory_impl.rb +0 -32
  314. data/ruby/neo4j/driver/internal/spi/connection.rb +0 -19
  315. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +0 -9
  316. data/ruby/neo4j/driver/internal/spi/response_handler.rb +0 -23
  317. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +0 -7
  318. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +0 -11
  319. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +0 -16
  320. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +0 -41
  321. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +0 -32
  322. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +0 -33
  323. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +0 -6
  324. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -18
  325. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +0 -196
  326. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +0 -21
  327. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +0 -65
  328. data/ruby/neo4j/driver/internal/util/clock.rb +0 -29
  329. data/ruby/neo4j/driver/internal/util/error_util.rb +0 -104
  330. data/ruby/neo4j/driver/internal/util/extract.rb +0 -123
  331. data/ruby/neo4j/driver/internal/util/format.rb +0 -39
  332. data/ruby/neo4j/driver/internal/util/futures.rb +0 -99
  333. data/ruby/neo4j/driver/internal/util/iterables.rb +0 -35
  334. data/ruby/neo4j/driver/internal/util/lock_util.rb +0 -23
  335. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +0 -101
  336. data/ruby/neo4j/driver/internal/util/mutex.rb +0 -9
  337. data/ruby/neo4j/driver/internal/util/preconditions.rb +0 -16
  338. data/ruby/neo4j/driver/internal/util/result_holder.rb +0 -72
  339. data/ruby/neo4j/driver/internal/util/server_version.rb +0 -60
  340. data/ruby/neo4j/driver/logging1.rb +0 -51
  341. data/ruby/neo4j/driver/net/server_address.rb +0 -9
  342. data/ruby/neo4j/driver/query.rb +0 -48
  343. data/ruby/neo4j/driver/records.rb +0 -13
  344. data/ruby/neo4j/driver/transaction_config.rb +0 -50
  345. data/ruby/neo4j/driver/values.rb +0 -26
  346. data/ruby/neo4j/driver.rb +0 -30
@@ -0,0 +1,232 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ # Bolt handshake negotiation. Two paths share the same 20-byte
7
+ # preamble (magic + four 4-byte slots, slot 1 = manifest sentinel):
8
+ #
9
+ # Legacy: server replies with one of the proposed versions
10
+ # (4 bytes, big-endian). Pre-5.7 servers always take
11
+ # this path because they don't speak manifest.
12
+ #
13
+ # Manifest v1: server replies with the sentinel 0x000001FF,
14
+ # then sends a varint count + N×4-byte version ranges +
15
+ # a varlong capabilities mask. Client picks the highest
16
+ # version it supports and writes back the chosen
17
+ # version (4 bytes) + a varlong of capabilities
18
+ # (currently always 0 — we negotiate no capabilities).
19
+ #
20
+ # Mirrors `BoltProtocolUtil` / `HandshakeHandler` / `ManifestHandlerV1`
21
+ # in neo4j-bolt-connection-java.
22
+ class Handshake
23
+ MAGIC_PREAMBLE = "\x60\x60\xB0\x17".b
24
+
25
+ # First four bytes of an HTTP response ("HTTP") read as a
26
+ # big-endian int — a server speaking HTTP on the Bolt port.
27
+ HTTP_REPLY = 0x4854_5450
28
+
29
+ # Slot 1 advertises "I speak HandshakeManifestV1". Decodes as
30
+ # BoltVersion(major=255, minor=1); servers that don't understand
31
+ # the sentinel ignore it and pick from slots 2-4 instead.
32
+ MANIFEST_SENTINEL = 0x00_00_01_FF
33
+
34
+ # Range encoding: [reserved=0, range=N, minor, major]. Each
35
+ # slot covers `major.minor` down to `major.(minor-N)`. We
36
+ # advertise 5.0–5.8 (slot 2), 4.2–4.4 (slot 3) and 3.0 (slot 4).
37
+ # Bolt 3.0 is fully wired now (Protocol::V3: PULL_ALL /
38
+ # DISCARD_ALL, single-DB, no routing in HELLO).
39
+ SLOTS = [
40
+ MANIFEST_SENTINEL,
41
+ 0x00_08_08_05, # 5.0–5.8
42
+ 0x00_02_04_04, # 4.2–4.4
43
+ 0x00_00_00_03 # 3.0
44
+ ].freeze
45
+
46
+ # Versions we'd accept from a manifest, highest-preference first.
47
+ # Used to pick a winner from whatever the server advertises.
48
+ SUPPORTED_VERSIONS = [
49
+ BoltVersion::V6_1,
50
+ BoltVersion::V6_0,
51
+ BoltVersion::V5_8,
52
+ BoltVersion::V5_7,
53
+ BoltVersion::V5_6,
54
+ BoltVersion::V5_5,
55
+ BoltVersion::V5_4,
56
+ BoltVersion::V5_3,
57
+ BoltVersion::V5_2,
58
+ BoltVersion::V5_1,
59
+ BoltVersion::V5_0,
60
+ BoltVersion::V4_4,
61
+ BoltVersion::V4_3,
62
+ BoltVersion::V4_2,
63
+ BoltVersion::V3_0
64
+ ].freeze
65
+
66
+ # `deadline` (monotonic) bounds the negotiation reads so a server that
67
+ # stalls the magic-byte exchange can't outlast the acquisition timeout.
68
+ # We read via wait_readable + read_nonblock rather than read(n)+IO#timeout
69
+ # because IO#timeout is honored for read() only on CRuby, not JRuby —
70
+ # wait_readable times out on both, so the bound works on every flavor.
71
+ def initialize(socket, deadline: nil, clock: Internal::Clock.new)
72
+ @socket = socket
73
+ @deadline = deadline
74
+ @clock = clock
75
+ end
76
+
77
+ # Run the handshake to completion. Returns the negotiated
78
+ # version as a 32-bit int in the wire's slot encoding
79
+ # ([reserved, range=0, minor, major]).
80
+ # Sanity cap on the manifest's range-count varint. The varint
81
+ # itself is bounded to 63 usable bits but a server (malicious
82
+ # or buggy) could still ask us to allocate billions of slots.
83
+ # 256 is comfortably above the realistic upper bound (Java
84
+ # currently advertises ~5 ranges) and well below anything
85
+ # that'd hurt to allocate.
86
+ MAX_MANIFEST_RANGES = 256
87
+
88
+ def negotiate
89
+ @socket.write(MAGIC_PREAMBLE)
90
+ SLOTS.each { |slot| @socket.write([slot].pack('L>')) }
91
+ @socket.flush
92
+
93
+ server_reply = read_int32!('Server closed the connection during handshake')
94
+ raise Exceptions::ServiceUnavailableException,
95
+ 'Server does not support any of the proposed Bolt versions' if server_reply.zero?
96
+
97
+ # An HTTP server on the Bolt port replies with an HTTP status
98
+ # line; its first four bytes spell "HTTP". Mirror Java's helpful
99
+ # error instead of reporting a bogus protocol version.
100
+ raise Exceptions::ClientException,
101
+ 'Server responded HTTP. Make sure you are not trying to connect to the http ' \
102
+ 'endpoint (HTTP defaults to port 7474 whereas BOLT defaults to port 7687)' if server_reply == HTTP_REPLY
103
+
104
+ server_reply == MANIFEST_SENTINEL ? negotiate_manifest : server_reply
105
+ end
106
+
107
+ private
108
+
109
+ # The manifest path: read the server's supported-version list
110
+ # and capabilities, pick the highest version we know, write
111
+ # back our choice + an empty-capabilities varlong.
112
+ def negotiate_manifest
113
+ count = read_varint
114
+ if count > MAX_MANIFEST_RANGES
115
+ raise Exceptions::ServiceUnavailableException,
116
+ "Server's manifest range count #{count} exceeds the #{MAX_MANIFEST_RANGES} cap"
117
+ end
118
+
119
+ ranges = Array.new(count) { read_int32!('Connection closed mid-manifest while reading version ranges') }
120
+ read_varlong # server capabilities — consume but ignore (no caps requested)
121
+
122
+ chosen = pick_version(ranges)
123
+ unless chosen
124
+ # Tell the server we couldn't agree (4 bytes of zero +
125
+ # zero-varlong cap), then bail. Same shape as Java's
126
+ # ManifestHandlerV1 no-match path.
127
+ @socket.write([0].pack('L>'))
128
+ write_varlong(0)
129
+ @socket.flush
130
+ raise Exceptions::ServiceUnavailableException,
131
+ "Server's manifest offered no Bolt version we support"
132
+ end
133
+
134
+ @socket.write([chosen.to_wire].pack('L>'))
135
+ # We don't request any capabilities yet (BoltCapability.FABRIC
136
+ # is the only one Java defines, and we don't use Fabric).
137
+ write_varlong(0)
138
+ @socket.flush
139
+
140
+ chosen.to_wire
141
+ end
142
+
143
+ # The server's version list comes as raw ints encoded
144
+ # `(minor_count << 16) | (minor << 8) | major`. Walk our
145
+ # preference list and pick the first that any advertised range
146
+ # covers.
147
+ def pick_version(ranges)
148
+ SUPPORTED_VERSIONS.find { |v| ranges.any? { |range_int| range_covers?(range_int, v) } }
149
+ end
150
+
151
+ def range_covers?(range_int, version)
152
+ major = range_int & 0xFF
153
+ top_minor = (range_int >> 8) & 0xFF
154
+ count = (range_int >> 16) & 0xFF
155
+ return false unless version.major == major
156
+
157
+ version.minor <= top_minor && version.minor >= top_minor - count
158
+ end
159
+
160
+ def read_int32
161
+ bytes = read_fully(4)
162
+ bytes ? bytes.unpack1('L>') : nil
163
+ end
164
+
165
+ # Read exactly n bytes, bounded by @deadline. Returns the bytes, or nil
166
+ # on EOF / deadline (callers turn nil into the right handshake error).
167
+ # wait_readable yields under a Fiber scheduler and times out on every
168
+ # Ruby (unlike read()+IO#timeout, which only times out on CRuby).
169
+ def read_fully(n)
170
+ buf = String.new(encoding: Encoding::BINARY)
171
+ while buf.bytesize < n
172
+ case (chunk = @socket.read_nonblock(n - buf.bytesize, exception: false))
173
+ when :wait_readable then (@socket.wait_readable(remaining_budget) || return)
174
+ when :wait_writable then (@socket.wait_writable(remaining_budget) || return)
175
+ when nil then return
176
+ else buf << chunk
177
+ end
178
+ end
179
+ buf
180
+ end
181
+
182
+ def remaining_budget
183
+ return nil unless @deadline
184
+
185
+ [@deadline - @clock.monotonic, 0.0].max
186
+ end
187
+
188
+ # Same as read_int32 but raises a ServiceUnavailableException
189
+ # on short read instead of returning nil. Use this whenever a
190
+ # nil result would propagate into bitmasks / arithmetic and
191
+ # crash with a less helpful TypeError downstream.
192
+ def read_int32!(message)
193
+ read_int32 || raise(Exceptions::ServiceUnavailableException, message)
194
+ end
195
+
196
+ # LEB128 unsigned varint / varlong. 7 data bits per byte, MSB
197
+ # is the continuation flag. Java caps at 9 bytes (63 usable
198
+ # bits) and so do we — anything wider is a malformed peer.
199
+ def read_varint
200
+ value = 0
201
+ shift = 0
202
+ 9.times do
203
+ byte = read_fully(1)&.unpack1('C')
204
+ raise IOError, 'Unexpected end of stream while reading varint' if byte.nil?
205
+
206
+ value |= (byte & 0x7F) << shift
207
+ return value if byte & 0x80 == 0
208
+
209
+ shift += 7
210
+ end
211
+ raise Exceptions::ServiceUnavailableException, 'Varint overflow during handshake'
212
+ end
213
+ alias read_varlong read_varint
214
+
215
+ def write_varlong(value)
216
+ # do/while so zero still emits a single 0x00 byte (matches
217
+ # Java's writeVarLong).
218
+ loop do
219
+ byte = value & 0x7F
220
+ value >>= 7
221
+ if value.zero?
222
+ @socket.write([byte].pack('C'))
223
+ break
224
+ else
225
+ @socket.write([byte | 0x80].pack('C'))
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ module Message
7
+ # Failure response from Neo4j server.
8
+ #
9
+ # Two wire shapes, both handled by #to_exception:
10
+ # * Legacy (pre-Bolt 5.7): { code:, message: }.
11
+ # * GQL (Bolt 5.7+): { gql_status:, description:, message:, neo4j_code:,
12
+ # diagnostic_record:, cause: } — `cause` nests the same shape.
13
+ # Since the driver speaks 5.7, a legacy failure is *synthesised* into the
14
+ # GQL shape (gql_status 50N42, default diagnostic record) so the exception
15
+ # exposes the same fields regardless of the server's protocol version —
16
+ # matching the Java driver's GqlStatusException behaviour.
17
+ class Failure
18
+ # Code-prefix → driver exception class. Order matters: more specific
19
+ # patterns must come first.
20
+ EXCEPTION_FOR_CODE = [
21
+ [%r{^Neo\.ClientError\.Security\.Unauthorized}, Exceptions::AuthenticationException],
22
+ [%r{^Neo\.ClientError\.Security\.AuthorizationExpired}, Exceptions::AuthorizationExpiredException],
23
+ [%r{^Neo\.ClientError\.Security\.TokenExpired}, Exceptions::TokenExpiredException],
24
+ [%r{^Neo\.ClientError\.Security}, Exceptions::SecurityException],
25
+ [%r{^Neo\.ClientError\.Database\.DatabaseNotFound}, Exceptions::FatalDiscoveryException],
26
+ [%r{^Neo\.ClientError}, Exceptions::ClientException],
27
+ [%r{^Neo\.TransientError}, Exceptions::TransientException],
28
+ [%r{^Neo\.DatabaseError}, Exceptions::DatabaseException]
29
+ ].freeze
30
+
31
+ # Two `TransientError` codes the server may send that are actually
32
+ # non-retryable: the driver rewrites them to their `ClientError` form
33
+ # (so they map to a non-retryable ClientException, not a retryable
34
+ # TransientException) and surfaces the rewritten code. Mirrors the
35
+ # Java driver's ErrorUtil special-case; testkit's
36
+ # test_should_not_retry_non_retryable_tx_failures asserts both the
37
+ # rewritten code and that the managed-tx executor does not retry.
38
+ CODE_REWRITES = {
39
+ 'Neo.TransientError.Transaction.Terminated' => 'Neo.ClientError.Transaction.Terminated',
40
+ 'Neo.TransientError.Transaction.LockClientStopped' => 'Neo.ClientError.Transaction.LockClientStopped'
41
+ }.freeze
42
+
43
+ # GQL diagnostic-record keys the server may omit; filled with these
44
+ # defaults so the record is always complete (mirrors the Java driver).
45
+ DEFAULT_DIAGNOSTIC_RECORD = { OPERATION: '', OPERATION_CODE: '0', CURRENT_SCHEMA: '/' }.freeze
46
+
47
+ # Fallback GQL status for a legacy (non-GQL) failure: 50N42 =
48
+ # "general processing exception - unexpected error".
49
+ DEFAULT_GQL_STATUS = '50N42'
50
+ DEFAULT_STATUS_DESCRIPTION_PREFIX = 'error: general processing exception - unexpected error. '
51
+
52
+ # Diagnostic-record classifications the spec recognises; anything else
53
+ # (or absent) surfaces as the catch-all UNKNOWN.
54
+ KNOWN_CLASSIFICATIONS = %w[CLIENT_ERROR DATABASE_ERROR TRANSIENT_ERROR].freeze
55
+
56
+ attr_reader :metadata
57
+
58
+ def initialize(metadata)
59
+ @metadata = metadata
60
+ end
61
+
62
+ def code
63
+ @metadata[:neo4j_code] || @metadata[:code]
64
+ end
65
+
66
+ def message
67
+ @metadata[:message]
68
+ end
69
+
70
+ # Map this server FAILURE to its driver-side exception. Single owner of
71
+ # the code→exception logic — used to live in 4+ places.
72
+ def to_exception
73
+ gql?(@metadata) ? build_gql(@metadata) : build_legacy(@metadata)
74
+ end
75
+
76
+ def accept(visitor)
77
+ visitor.on_failure(self)
78
+ end
79
+
80
+ def assert_success!
81
+ raise to_exception
82
+ end
83
+
84
+ def terminal? = true
85
+
86
+ private
87
+
88
+ def gql?(meta) = meta.key?(:gql_status)
89
+
90
+ def exception_class(code)
91
+ (EXCEPTION_FOR_CODE.find { |pattern, _| code.to_s.match?(pattern) }&.last if code) ||
92
+ Exceptions::Neo4jException
93
+ end
94
+
95
+ # A handful of TransientError codes are non-retryable and surface
96
+ # under their ClientError code (see CODE_REWRITES).
97
+ def rewrite_code(code) = CODE_REWRITES[code] || code
98
+
99
+ # Bolt 5.7+ GQL failure: read the fields straight off the wire, fill the
100
+ # diagnostic-record defaults, and recurse into the cause chain.
101
+ def build_gql(meta)
102
+ diagnostic_record = fill_defaults(meta[:diagnostic_record])
103
+ raw_classification = diagnostic_record[:_classification]
104
+ raw_classification = nil unless raw_classification.is_a?(String)
105
+
106
+ code = rewrite_code(meta[:neo4j_code])
107
+ exception_class(code).new(
108
+ meta[:message],
109
+ code: code,
110
+ gql_status: meta[:gql_status],
111
+ status_description: meta[:description],
112
+ diagnostic_record: diagnostic_record,
113
+ raw_classification: raw_classification,
114
+ classification: (raw_classification if KNOWN_CLASSIFICATIONS.include?(raw_classification)),
115
+ gql_cause: meta[:cause] && build_gql(meta[:cause])
116
+ )
117
+ end
118
+
119
+ # Legacy { code:, message: } failure — synthesise the GQL shape so the
120
+ # exception carries the same fields a 5.7 server would have sent.
121
+ def build_legacy(meta)
122
+ code = rewrite_code(meta[:code])
123
+ exception_class(code).new(
124
+ meta[:message],
125
+ code: code,
126
+ gql_status: DEFAULT_GQL_STATUS,
127
+ status_description: "#{DEFAULT_STATUS_DESCRIPTION_PREFIX}#{meta[:message]}",
128
+ diagnostic_record: DEFAULT_DIAGNOSTIC_RECORD.dup
129
+ )
130
+ end
131
+
132
+ def fill_defaults(record)
133
+ DEFAULT_DIAGNOSTIC_RECORD.merge(record || {})
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ module Message
7
+ # Ignored response from Neo4j server (previous request was ignored)
8
+ class Ignored
9
+ def initialize(metadata = {})
10
+ @metadata = metadata
11
+ end
12
+
13
+ def accept(visitor)
14
+ visitor.on_ignored(self)
15
+ end
16
+
17
+ def assert_success!
18
+ raise Exceptions::ClientException,
19
+ 'Server IGNORED the request — a previous request in this batch failed'
20
+ end
21
+
22
+ def terminal? = true
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ module Message
7
+ # Record response from Neo4j server containing result data
8
+ class Record
9
+ attr_reader :fields
10
+
11
+ def initialize(fields)
12
+ @fields = fields
13
+ end
14
+
15
+ def accept(visitor)
16
+ visitor.on_record(self)
17
+ end
18
+
19
+ def assert_success!
20
+ raise Exceptions::ClientException, "Unexpected RECORD where SUCCESS was expected"
21
+ end
22
+
23
+ # A RECORD is a streamed row, not a request summary — it never
24
+ # completes the request, so it doesn't decrement the in-flight count.
25
+ def terminal? = false
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ module Message
7
+ # Success response from Neo4j server
8
+ class Success
9
+ attr_reader :metadata
10
+
11
+ def initialize(metadata = {})
12
+ @metadata = metadata
13
+ end
14
+
15
+ # Visitor double-dispatch: streaming consumers use this to avoid
16
+ # `case/when` on the response class.
17
+ def accept(visitor)
18
+ visitor.on_success(self)
19
+ end
20
+
21
+ # One-shot pattern: caller expects a SUCCESS, raises otherwise.
22
+ # Returns self so callers can chain `.metadata`.
23
+ def assert_success!
24
+ self
25
+ end
26
+
27
+ # A SUCCESS completes the request it answers — the connection uses
28
+ # this to tell summary responses apart from streamed RECORDs.
29
+ def terminal? = true
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j
4
+ module Driver
5
+ module Bolt
6
+ # Bolt Protocol Messages
7
+ module Message
8
+ # Request messages (sent from client to server)
9
+ HELLO = 0x01
10
+ GOODBYE = 0x02
11
+ RESET = 0x0F
12
+ RUN = 0x10
13
+ BEGIN_TX = 0x11
14
+ COMMIT = 0x12
15
+ ROLLBACK = 0x13
16
+ PULL = 0x3F
17
+ DISCARD = 0x2F
18
+ ROUTE = 0x66
19
+ LOGON = 0x6A
20
+ LOGOFF = 0x6B
21
+ TELEMETRY = 0x54
22
+
23
+ # Response messages (sent from server to client)
24
+ SUCCESS = 0x70
25
+ RECORD = 0x71
26
+ IGNORED = 0x7E
27
+ FAILURE = 0x7F
28
+
29
+ class << self
30
+ # Note: HELLO message building is now handled by protocol-specific handlers
31
+ # This method kept for backward compatibility but shouldn't be used directly
32
+ def hello(user_agent:, auth:, routing: nil)
33
+ extra = { user_agent: user_agent }
34
+ extra[:routing] = routing if routing
35
+ # Default to Bolt 5.0+ format (merged auth)
36
+ extra.merge!(auth) if auth
37
+ PackStream::Structure.new(HELLO, [extra])
38
+ end
39
+
40
+ def run(query, parameters = {}, extra = {})
41
+ PackStream::Structure.new(RUN, [query, parameters, extra])
42
+ end
43
+
44
+ def begin_transaction(extra = {})
45
+ PackStream::Structure.new(BEGIN_TX, [extra])
46
+ end
47
+
48
+ def commit
49
+ PackStream::Structure.new(COMMIT, [])
50
+ end
51
+
52
+ def rollback
53
+ PackStream::Structure.new(ROLLBACK, [])
54
+ end
55
+
56
+ # Caller must specify n explicitly — Java/Python default is 1000
57
+ # records per batch but the call site (Session/Transaction) knows
58
+ # the configured fetch_size and passes it through. Default-here
59
+ # would silently mask "forgot to plumb fetch_size".
60
+ def pull(extra = {})
61
+ PackStream::Structure.new(PULL, [extra])
62
+ end
63
+
64
+ def discard(extra = {})
65
+ extra = { n: -1 }.merge(extra)
66
+ PackStream::Structure.new(DISCARD, [extra])
67
+ end
68
+
69
+ # Bolt 5.4+ TELEMETRY: reports which driver API opened the coming
70
+ # transaction/query (0 tx-function, 1 unmanaged tx, 2 auto-commit,
71
+ # 3 execute_query). Sent only when the server advertised
72
+ # `telemetry.enabled` and the driver didn't disable it.
73
+ def telemetry(api)
74
+ PackStream::Structure.new(TELEMETRY, [api])
75
+ end
76
+
77
+ def reset
78
+ PackStream::Structure.new(RESET, [])
79
+ end
80
+
81
+ def goodbye
82
+ PackStream::Structure.new(GOODBYE, [])
83
+ end
84
+
85
+ # LOGON (Bolt 5.1+). Carries the auth fields that 5.0 used to
86
+ # send inside HELLO. The server's success here marks the
87
+ # connection authenticated and READY.
88
+ def logon(auth)
89
+ PackStream::Structure.new(LOGON, [auth || {}])
90
+ end
91
+
92
+ # LOGOFF (Bolt 5.1+). De-authenticates the connection; the
93
+ # next LOGON re-authenticates with a possibly-different
94
+ # token. Used by per-session auth (`driver.session(auth: …)`)
95
+ # to switch identity on a pooled connection without tearing
96
+ # it down.
97
+ def logoff
98
+ PackStream::Structure.new(LOGOFF, [])
99
+ end
100
+
101
+ # ROUTE (Bolt 4.3+) — fetch the cluster's routing table.
102
+ # routing_context : map (typically built from the URI query string)
103
+ # bookmarks : list of bookmarks (or nil for Bolt 4.3 compat)
104
+ # extra : {db: <database or nil>, imp_user: <or nil>}
105
+ def route(routing_context, bookmarks, extra)
106
+ PackStream::Structure.new(ROUTE, [routing_context, bookmarks, extra])
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end