neo4j-ruby-driver 6.0.3.alpha.0 → 6.2.1.beta.2

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 (348) 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 +1091 -0
  9. data/lib/neo4j/driver/bolt/handshake.rb +236 -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 +143 -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 +262 -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/no_such_record_exception.rb +1 -1
  48. data/lib/neo4j/driver/exceptions/protocol_exception.rb +0 -5
  49. data/lib/neo4j/driver/exceptions/security_retryable_exception.rb +14 -0
  50. data/lib/neo4j/driver/exceptions/transaction_terminated_exception.rb +13 -0
  51. data/lib/neo4j/driver/graph_database.rb +29 -0
  52. data/lib/neo4j/driver/internal/clock.rb +20 -0
  53. data/lib/neo4j/driver/internal/clock_adapter.rb +21 -0
  54. data/lib/neo4j/driver/internal/default_bookmark_manager.rb +54 -0
  55. data/lib/neo4j/driver/internal/deprecator.rb +9 -5
  56. data/lib/neo4j/driver/internal/driver_factory.rb +128 -0
  57. data/lib/neo4j/driver/internal/duration_normalizer.rb +14 -39
  58. data/lib/neo4j/driver/internal/extras.rb +23 -0
  59. data/lib/neo4j/driver/internal/home_db_cache.rb +57 -0
  60. data/lib/neo4j/driver/internal/internal_auth_token_manager.rb +37 -0
  61. data/lib/neo4j/driver/internal/metrics.rb +31 -0
  62. data/lib/neo4j/driver/internal/security/static_auth_token_manager.rb +25 -0
  63. data/lib/neo4j/driver/internal/validator.rb +16 -2
  64. data/lib/neo4j/driver/net.rb +29 -0
  65. data/lib/neo4j/driver/packstream/markers.rb +49 -0
  66. data/lib/neo4j/driver/packstream/packer.rb +335 -0
  67. data/lib/neo4j/driver/packstream/structure.rb +27 -0
  68. data/lib/neo4j/driver/packstream/unpacker.rb +170 -0
  69. data/lib/neo4j/driver/record.rb +43 -0
  70. data/lib/neo4j/driver/result.rb +282 -0
  71. data/lib/neo4j/driver/routing/load_balancer.rb +706 -0
  72. data/lib/neo4j/driver/routing/routed_connection.rb +132 -0
  73. data/lib/neo4j/driver/routing/routing_table.rb +127 -0
  74. data/lib/neo4j/driver/routing/server_address.rb +25 -0
  75. data/lib/neo4j/driver/routing_control.rb +13 -0
  76. data/lib/neo4j/driver/session.rb +577 -0
  77. data/lib/neo4j/driver/summary/database_info.rb +25 -0
  78. data/lib/neo4j/driver/summary/gql_notification.rb +38 -0
  79. data/lib/neo4j/driver/summary/gql_status_object.rb +35 -0
  80. data/lib/neo4j/driver/summary/notification.rb +46 -0
  81. data/lib/neo4j/driver/summary/plan.rb +23 -0
  82. data/lib/neo4j/driver/summary/profile.rb +28 -0
  83. data/lib/neo4j/driver/summary/query.rb +19 -0
  84. data/lib/neo4j/driver/summary/query_type.rb +5 -1
  85. data/lib/neo4j/driver/summary/result_summary.rb +215 -0
  86. data/lib/neo4j/driver/summary/server_info.rb +33 -0
  87. data/lib/neo4j/driver/summary/summary_counters.rb +72 -0
  88. data/lib/neo4j/driver/transaction.rb +344 -0
  89. data/lib/neo4j/driver/types/duration.rb +76 -0
  90. data/lib/neo4j/driver/types/entity.rb +40 -0
  91. data/lib/neo4j/driver/types/local_date_time.rb +77 -8
  92. data/lib/neo4j/driver/types/local_time.rb +50 -7
  93. data/lib/neo4j/driver/types/node.rb +18 -0
  94. data/lib/neo4j/driver/types/offset_time.rb +78 -7
  95. data/lib/neo4j/driver/types/path.rb +68 -0
  96. data/lib/neo4j/driver/types/point.rb +38 -18
  97. data/lib/neo4j/driver/types/relationship.rb +32 -0
  98. data/lib/neo4j/driver/types/temporal_value.rb +44 -0
  99. data/lib/neo4j/driver/types/unbound_relationship.rb +24 -0
  100. data/lib/neo4j/driver/types/unresolvable_zoned_date_time.rb +38 -0
  101. data/lib/neo4j/driver/types/unsupported_type.rb +25 -0
  102. data/lib/neo4j/driver/types/uuid.rb +29 -0
  103. data/{ruby → lib}/neo4j/driver/version.rb +1 -1
  104. data/lib/neo4j/driver.rb +15 -0
  105. data/lib/neo4j-ruby-driver_loader.rb +34 -20
  106. metadata +115 -441
  107. data/lib/neo4j/driver/internal/bolt_server_address.rb +0 -97
  108. data/lib/neo4j/driver/synchronizable.rb +0 -23
  109. data/lib/neo4j/driver/types/time.rb +0 -45
  110. data/ruby/neo4j/driver/auth_tokens.rb +0 -34
  111. data/ruby/neo4j/driver/bookmark.rb +0 -21
  112. data/ruby/neo4j/driver/config.rb +0 -89
  113. data/ruby/neo4j/driver/graph_database.rb +0 -78
  114. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +0 -51
  115. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +0 -22
  116. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +0 -31
  117. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +0 -32
  118. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +0 -83
  119. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +0 -22
  120. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +0 -30
  121. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +0 -83
  122. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +0 -27
  123. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +0 -113
  124. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +0 -57
  125. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +0 -26
  126. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +0 -19
  127. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +0 -36
  128. data/ruby/neo4j/driver/internal/async/connection/stream.rb +0 -12
  129. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +0 -16
  130. data/ruby/neo4j/driver/internal/async/connection_context.rb +0 -10
  131. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +0 -24
  132. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +0 -30
  133. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +0 -77
  134. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +0 -41
  135. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +0 -32
  136. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +0 -17
  137. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +0 -171
  138. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +0 -42
  139. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +0 -51
  140. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +0 -92
  141. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +0 -13
  142. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +0 -34
  143. data/ruby/neo4j/driver/internal/async/network_connection.rb +0 -194
  144. data/ruby/neo4j/driver/internal/async/network_session.rb +0 -150
  145. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +0 -110
  146. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +0 -39
  147. data/ruby/neo4j/driver/internal/async/pool/channel.rb +0 -66
  148. data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +0 -31
  149. data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +0 -135
  150. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +0 -156
  151. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +0 -87
  152. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +0 -52
  153. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +0 -21
  154. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +0 -34
  155. data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +0 -15
  156. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +0 -17
  157. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +0 -212
  158. data/ruby/neo4j/driver/internal/bookmark_holder.rb +0 -9
  159. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +0 -48
  160. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +0 -14
  161. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +0 -122
  162. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +0 -10
  163. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +0 -68
  164. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +0 -125
  165. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +0 -13
  166. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +0 -31
  167. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +0 -147
  168. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +0 -43
  169. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +0 -77
  170. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +0 -60
  171. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +0 -35
  172. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +0 -24
  173. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +0 -95
  174. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +0 -121
  175. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +0 -73
  176. data/ruby/neo4j/driver/internal/connection_settings.rb +0 -16
  177. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +0 -55
  178. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +0 -24
  179. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +0 -61
  180. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +0 -24
  181. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +0 -110
  182. data/ruby/neo4j/driver/internal/database_name_util.rb +0 -37
  183. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +0 -9
  184. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +0 -11
  185. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +0 -40
  186. data/ruby/neo4j/driver/internal/driver_factory.rb +0 -126
  187. data/ruby/neo4j/driver/internal/eager_result_value.rb +0 -5
  188. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +0 -20
  189. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +0 -30
  190. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +0 -23
  191. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +0 -65
  192. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +0 -34
  193. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +0 -199
  194. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +0 -16
  195. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +0 -29
  196. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +0 -32
  197. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +0 -169
  198. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +0 -298
  199. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +0 -20
  200. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +0 -34
  201. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +0 -25
  202. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +0 -21
  203. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +0 -79
  204. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +0 -38
  205. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +0 -34
  206. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +0 -20
  207. data/ruby/neo4j/driver/internal/impersonation_util.rb +0 -22
  208. data/ruby/neo4j/driver/internal/internal_bookmark.rb +0 -9
  209. data/ruby/neo4j/driver/internal/internal_database_name.rb +0 -9
  210. data/ruby/neo4j/driver/internal/internal_driver.rb +0 -83
  211. data/ruby/neo4j/driver/internal/internal_entity.rb +0 -21
  212. data/ruby/neo4j/driver/internal/internal_node.rb +0 -21
  213. data/ruby/neo4j/driver/internal/internal_pair.rb +0 -9
  214. data/ruby/neo4j/driver/internal/internal_path.rb +0 -35
  215. data/ruby/neo4j/driver/internal/internal_point2_d.rb +0 -9
  216. data/ruby/neo4j/driver/internal/internal_point3_d.rb +0 -6
  217. data/ruby/neo4j/driver/internal/internal_record.rb +0 -27
  218. data/ruby/neo4j/driver/internal/internal_relationship.rb +0 -27
  219. data/ruby/neo4j/driver/internal/internal_result.rb +0 -49
  220. data/ruby/neo4j/driver/internal/internal_session.rb +0 -91
  221. data/ruby/neo4j/driver/internal/internal_transaction.rb +0 -48
  222. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +0 -29
  223. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +0 -17
  224. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +0 -19
  225. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +0 -17
  226. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +0 -23
  227. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -32
  228. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +0 -48
  229. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +0 -51
  230. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +0 -33
  231. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +0 -104
  232. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +0 -256
  233. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +0 -15
  234. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +0 -14
  235. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +0 -14
  236. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +0 -15
  237. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +0 -14
  238. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +0 -15
  239. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +0 -16
  240. data/ruby/neo4j/driver/internal/messaging/encode/logoff_message_encoder.rb +0 -14
  241. data/ruby/neo4j/driver/internal/messaging/encode/logon_message_encoder.rb +0 -15
  242. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +0 -14
  243. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +0 -15
  244. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +0 -14
  245. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +0 -14
  246. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +0 -24
  247. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +0 -22
  248. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +0 -16
  249. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +0 -17
  250. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +0 -25
  251. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +0 -25
  252. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +0 -20
  253. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +0 -20
  254. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +0 -23
  255. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +0 -20
  256. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +0 -30
  257. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +0 -19
  258. data/ruby/neo4j/driver/internal/messaging/request/logoff_message.rb +0 -13
  259. data/ruby/neo4j/driver/internal/messaging/request/logon_message.rb +0 -13
  260. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +0 -17
  261. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +0 -26
  262. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +0 -23
  263. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +0 -22
  264. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +0 -32
  265. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +0 -20
  266. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +0 -28
  267. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +0 -23
  268. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +0 -49
  269. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +0 -24
  270. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +0 -40
  271. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +0 -29
  272. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +0 -33
  273. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +0 -34
  274. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -82
  275. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +0 -17
  276. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +0 -27
  277. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +0 -29
  278. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +0 -13
  279. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +0 -17
  280. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +0 -25
  281. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +0 -13
  282. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +0 -19
  283. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +0 -14
  284. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +0 -20
  285. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +0 -17
  286. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +0 -14
  287. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +0 -15
  288. data/ruby/neo4j/driver/internal/messaging/v5/bolt_protocol_v5.rb +0 -21
  289. data/ruby/neo4j/driver/internal/messaging/v5/message_format_v5.rb +0 -18
  290. data/ruby/neo4j/driver/internal/messaging/v5/value_unpacker_v5.rb +0 -17
  291. data/ruby/neo4j/driver/internal/messaging/v51/bolt_protocol_v51.rb +0 -40
  292. data/ruby/neo4j/driver/internal/messaging/v51/message_format_v51.rb +0 -14
  293. data/ruby/neo4j/driver/internal/messaging/v51/message_writer_v51.rb +0 -17
  294. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +0 -34
  295. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +0 -46
  296. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +0 -105
  297. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +0 -82
  298. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +0 -18
  299. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +0 -17
  300. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +0 -24
  301. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +0 -15
  302. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +0 -12
  303. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +0 -47
  304. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +0 -39
  305. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +0 -324
  306. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +0 -17
  307. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +0 -13
  308. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +0 -35
  309. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -150
  310. data/ruby/neo4j/driver/internal/revocation_strategy.rb +0 -19
  311. data/ruby/neo4j/driver/internal/scheme.rb +0 -32
  312. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +0 -15
  313. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +0 -48
  314. data/ruby/neo4j/driver/internal/security_setting.rb +0 -66
  315. data/ruby/neo4j/driver/internal/session_factory_impl.rb +0 -32
  316. data/ruby/neo4j/driver/internal/spi/connection.rb +0 -19
  317. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +0 -9
  318. data/ruby/neo4j/driver/internal/spi/response_handler.rb +0 -23
  319. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +0 -7
  320. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +0 -11
  321. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +0 -16
  322. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +0 -41
  323. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +0 -32
  324. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +0 -33
  325. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +0 -6
  326. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -18
  327. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +0 -196
  328. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +0 -21
  329. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +0 -65
  330. data/ruby/neo4j/driver/internal/util/clock.rb +0 -29
  331. data/ruby/neo4j/driver/internal/util/error_util.rb +0 -104
  332. data/ruby/neo4j/driver/internal/util/extract.rb +0 -123
  333. data/ruby/neo4j/driver/internal/util/format.rb +0 -39
  334. data/ruby/neo4j/driver/internal/util/futures.rb +0 -99
  335. data/ruby/neo4j/driver/internal/util/iterables.rb +0 -35
  336. data/ruby/neo4j/driver/internal/util/lock_util.rb +0 -23
  337. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +0 -101
  338. data/ruby/neo4j/driver/internal/util/mutex.rb +0 -9
  339. data/ruby/neo4j/driver/internal/util/preconditions.rb +0 -16
  340. data/ruby/neo4j/driver/internal/util/result_holder.rb +0 -72
  341. data/ruby/neo4j/driver/internal/util/server_version.rb +0 -60
  342. data/ruby/neo4j/driver/logging1.rb +0 -51
  343. data/ruby/neo4j/driver/net/server_address.rb +0 -9
  344. data/ruby/neo4j/driver/query.rb +0 -48
  345. data/ruby/neo4j/driver/records.rb +0 -13
  346. data/ruby/neo4j/driver/transaction_config.rb +0 -50
  347. data/ruby/neo4j/driver/values.rb +0 -26
  348. data/ruby/neo4j/driver.rb +0 -30
@@ -0,0 +1,236 @@
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
+ if server_reply.zero?
95
+ raise Exceptions::ServiceUnavailableException,
96
+ 'Server does not support any of the proposed Bolt versions'
97
+ end
98
+
99
+ # An HTTP server on the Bolt port replies with an HTTP status
100
+ # line; its first four bytes spell "HTTP". Mirror Java's helpful
101
+ # error instead of reporting a bogus protocol version.
102
+ if server_reply == HTTP_REPLY
103
+ raise Exceptions::ClientException,
104
+ 'Server responded HTTP. Make sure you are not trying to connect to the http ' \
105
+ 'endpoint (HTTP defaults to port 7474 whereas BOLT defaults to port 7687)'
106
+ end
107
+
108
+ server_reply == MANIFEST_SENTINEL ? negotiate_manifest : server_reply
109
+ end
110
+
111
+ private
112
+
113
+ # The manifest path: read the server's supported-version list
114
+ # and capabilities, pick the highest version we know, write
115
+ # back our choice + an empty-capabilities varlong.
116
+ def negotiate_manifest
117
+ count = read_varint
118
+ if count > MAX_MANIFEST_RANGES
119
+ raise Exceptions::ServiceUnavailableException,
120
+ "Server's manifest range count #{count} exceeds the #{MAX_MANIFEST_RANGES} cap"
121
+ end
122
+
123
+ ranges = Array.new(count) { read_int32!('Connection closed mid-manifest while reading version ranges') }
124
+ read_varlong # server capabilities — consume but ignore (no caps requested)
125
+
126
+ chosen = pick_version(ranges)
127
+ unless chosen
128
+ # Tell the server we couldn't agree (4 bytes of zero +
129
+ # zero-varlong cap), then bail. Same shape as Java's
130
+ # ManifestHandlerV1 no-match path.
131
+ @socket.write([0].pack('L>'))
132
+ write_varlong(0)
133
+ @socket.flush
134
+ raise Exceptions::ServiceUnavailableException,
135
+ "Server's manifest offered no Bolt version we support"
136
+ end
137
+
138
+ @socket.write([chosen.to_wire].pack('L>'))
139
+ # We don't request any capabilities yet (BoltCapability.FABRIC
140
+ # is the only one Java defines, and we don't use Fabric).
141
+ write_varlong(0)
142
+ @socket.flush
143
+
144
+ chosen.to_wire
145
+ end
146
+
147
+ # The server's version list comes as raw ints encoded
148
+ # `(minor_count << 16) | (minor << 8) | major`. Walk our
149
+ # preference list and pick the first that any advertised range
150
+ # covers.
151
+ def pick_version(ranges)
152
+ SUPPORTED_VERSIONS.find { |v| ranges.any? { |range_int| range_covers?(range_int, v) } }
153
+ end
154
+
155
+ def range_covers?(range_int, version)
156
+ major = range_int & 0xFF
157
+ top_minor = (range_int >> 8) & 0xFF
158
+ count = (range_int >> 16) & 0xFF
159
+ return false unless version.major == major
160
+
161
+ version.minor <= top_minor && version.minor >= top_minor - count
162
+ end
163
+
164
+ def read_int32
165
+ bytes = read_fully(4)
166
+ bytes ? bytes.unpack1('L>') : nil
167
+ end
168
+
169
+ # Read exactly n bytes, bounded by @deadline. Returns the bytes, or nil
170
+ # on EOF / deadline (callers turn nil into the right handshake error).
171
+ # wait_readable yields under a Fiber scheduler and times out on every
172
+ # Ruby (unlike read()+IO#timeout, which only times out on CRuby).
173
+ def read_fully(n)
174
+ buf = String.new(encoding: Encoding::BINARY)
175
+ while buf.bytesize < n
176
+ case (chunk = @socket.read_nonblock(n - buf.bytesize, exception: false))
177
+ when :wait_readable then @socket.wait_readable(remaining_budget) || return
178
+ when :wait_writable then @socket.wait_writable(remaining_budget) || return
179
+ when nil then return
180
+ else buf << chunk
181
+ end
182
+ end
183
+ buf
184
+ end
185
+
186
+ def remaining_budget
187
+ return nil unless @deadline
188
+
189
+ [@deadline - @clock.monotonic, 0.0].max
190
+ end
191
+
192
+ # Same as read_int32 but raises a ServiceUnavailableException
193
+ # on short read instead of returning nil. Use this whenever a
194
+ # nil result would propagate into bitmasks / arithmetic and
195
+ # crash with a less helpful TypeError downstream.
196
+ def read_int32!(message)
197
+ read_int32 || raise(Exceptions::ServiceUnavailableException, message)
198
+ end
199
+
200
+ # LEB128 unsigned varint / varlong. 7 data bits per byte, MSB
201
+ # is the continuation flag. Java caps at 9 bytes (63 usable
202
+ # bits) and so do we — anything wider is a malformed peer.
203
+ def read_varint
204
+ value = 0
205
+ shift = 0
206
+ 9.times do
207
+ byte = read_fully(1)&.unpack1('C')
208
+ raise IOError, 'Unexpected end of stream while reading varint' if byte.nil?
209
+
210
+ value |= (byte & 0x7F) << shift
211
+ return value if byte & 0x80 == 0
212
+
213
+ shift += 7
214
+ end
215
+ raise Exceptions::ServiceUnavailableException, 'Varint overflow during handshake'
216
+ end
217
+ alias read_varlong read_varint
218
+
219
+ def write_varlong(value)
220
+ # do/while so zero still emits a single 0x00 byte (matches
221
+ # Java's writeVarLong).
222
+ loop do
223
+ byte = value & 0x7F
224
+ value >>= 7
225
+ if value.zero?
226
+ @socket.write([byte].pack('C'))
227
+ break
228
+ else
229
+ @socket.write([byte | 0x80].pack('C'))
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ 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
+ [/^Neo\.ClientError\.Security\.Unauthorized/, Exceptions::AuthenticationException],
22
+ [/^Neo\.ClientError\.Security\.AuthorizationExpired/, Exceptions::AuthorizationExpiredException],
23
+ [/^Neo\.ClientError\.Security\.TokenExpired/, Exceptions::TokenExpiredException],
24
+ [/^Neo\.ClientError\.Security/, Exceptions::SecurityException],
25
+ [/^Neo\.ClientError\.Database\.DatabaseNotFound/, Exceptions::FatalDiscoveryException],
26
+ [/^Neo\.ClientError/, Exceptions::ClientException],
27
+ [/^Neo\.TransientError/, Exceptions::TransientException],
28
+ [/^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