neo4j-ruby-driver 1.7.4 → 4.4.0

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 (342) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -42
  3. data/lib/loader.rb +5 -3
  4. data/lib/neo4j/driver/auto_closable.rb +2 -2
  5. data/lib/neo4j/driver/exceptions/authentication_exception.rb +6 -1
  6. data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
  7. data/lib/neo4j/driver/{types/bytes.rb → exceptions/certificate_exception.rb} +2 -2
  8. data/lib/neo4j/driver/exceptions/client_exception.rb +3 -0
  9. data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
  10. data/lib/neo4j/driver/exceptions/database_exception.rb +3 -0
  11. data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
  12. data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
  13. data/lib/neo4j/driver/exceptions/protocol_exception.rb +7 -0
  14. data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
  15. data/lib/neo4j/driver/exceptions/security_exception.rb +5 -1
  16. data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +2 -0
  17. data/lib/neo4j/driver/exceptions/session_expired_exception.rb +4 -0
  18. data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
  19. data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
  20. data/lib/neo4j/driver/exceptions/transient_exception.rb +3 -0
  21. data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +1 -0
  22. data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
  23. data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
  24. data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
  25. data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
  26. data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
  27. data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
  28. data/lib/neo4j/driver/internal/duration_normalizer.rb +1 -1
  29. data/lib/neo4j/driver/internal/validator.rb +5 -4
  30. data/{ffi/neo4j/driver/summary/statement_type.rb → lib/neo4j/driver/summary/query_type.rb} +1 -3
  31. data/lib/neo4j/driver/synchronizable.rb +23 -0
  32. data/lib/neo4j/driver/types/time.rb +4 -2
  33. data/lib/neo4j_ruby_driver.rb +5 -10
  34. data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
  35. data/ruby/neo4j/driver/auth_tokens.rb +34 -0
  36. data/ruby/neo4j/driver/bookmark.rb +21 -0
  37. data/ruby/neo4j/driver/config.rb +89 -0
  38. data/ruby/neo4j/driver/graph_database.rb +80 -0
  39. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
  40. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
  41. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
  42. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
  43. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +83 -0
  44. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
  45. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
  46. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
  47. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
  48. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
  49. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
  50. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
  51. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
  52. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
  53. data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
  54. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
  55. data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
  56. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
  57. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
  58. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
  59. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
  60. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
  61. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
  62. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +171 -0
  63. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
  64. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
  65. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
  66. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
  67. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
  68. data/ruby/neo4j/driver/internal/async/network_connection.rb +194 -0
  69. data/ruby/neo4j/driver/internal/async/network_session.rb +150 -0
  70. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
  71. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
  72. data/ruby/neo4j/driver/internal/async/pool/channel.rb +62 -0
  73. data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +31 -0
  74. data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +135 -0
  75. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +156 -0
  76. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
  77. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
  78. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
  79. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
  80. data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +15 -0
  81. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
  82. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +212 -0
  83. data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
  84. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +48 -0
  85. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
  86. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +122 -0
  87. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +10 -0
  88. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
  89. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +125 -0
  90. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
  91. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +31 -0
  92. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +147 -0
  93. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
  94. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
  95. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +60 -0
  96. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +35 -0
  97. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
  98. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +95 -0
  99. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +121 -0
  100. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +73 -0
  101. data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
  102. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +55 -0
  103. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +24 -0
  104. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +61 -0
  105. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +24 -0
  106. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
  107. data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
  108. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +9 -0
  109. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
  110. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
  111. data/ruby/neo4j/driver/internal/driver_factory.rb +126 -0
  112. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
  113. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +30 -0
  114. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
  115. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
  116. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
  117. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +199 -0
  118. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
  119. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
  120. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
  121. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +168 -0
  122. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +298 -0
  123. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
  124. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
  125. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +25 -0
  126. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
  127. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
  128. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +38 -0
  129. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
  130. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
  131. data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
  132. data/ruby/neo4j/driver/internal/internal_bookmark.rb +36 -0
  133. data/ruby/neo4j/driver/internal/internal_database_name.rb +9 -0
  134. data/ruby/neo4j/driver/internal/internal_driver.rb +74 -0
  135. data/ruby/neo4j/driver/internal/internal_entity.rb +20 -0
  136. data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
  137. data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
  138. data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
  139. data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
  140. data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
  141. data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
  142. data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
  143. data/ruby/neo4j/driver/internal/internal_result.rb +49 -0
  144. data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
  145. data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
  146. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
  147. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
  148. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
  149. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
  150. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
  151. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
  152. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +48 -0
  153. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
  154. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
  155. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
  156. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
  157. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
  158. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
  159. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
  160. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
  161. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
  162. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
  163. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
  164. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
  165. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
  166. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
  167. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
  168. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +24 -0
  169. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +22 -0
  170. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
  171. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
  172. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +25 -0
  173. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +25 -0
  174. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
  175. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
  176. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
  177. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
  178. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
  179. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
  180. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
  181. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
  182. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
  183. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
  184. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
  185. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
  186. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +28 -0
  187. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
  188. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +49 -0
  189. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
  190. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
  191. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
  192. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
  193. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
  194. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +82 -0
  195. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
  196. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
  197. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
  198. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
  199. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +17 -0
  200. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
  201. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
  202. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
  203. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
  204. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +20 -0
  205. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
  206. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
  207. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +15 -0
  208. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
  209. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
  210. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
  211. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
  212. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
  213. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
  214. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
  215. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
  216. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
  217. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
  218. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
  219. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
  220. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
  221. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
  222. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
  223. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
  224. data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
  225. data/ruby/neo4j/driver/internal/scheme.rb +32 -0
  226. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
  227. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +48 -0
  228. data/ruby/neo4j/driver/internal/security_setting.rb +66 -0
  229. data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
  230. data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
  231. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
  232. data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
  233. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
  234. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
  235. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
  236. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
  237. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
  238. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
  239. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
  240. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
  241. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
  242. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
  243. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
  244. data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
  245. data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
  246. data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
  247. data/ruby/neo4j/driver/internal/util/format.rb +39 -0
  248. data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
  249. data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
  250. data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
  251. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +107 -0
  252. data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
  253. data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
  254. data/ruby/neo4j/driver/internal/util/result_holder.rb +72 -0
  255. data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
  256. data/ruby/neo4j/driver/logging1.rb +51 -0
  257. data/ruby/neo4j/driver/net/server_address.rb +9 -0
  258. data/ruby/neo4j/driver/query.rb +48 -0
  259. data/ruby/neo4j/driver/records.rb +13 -0
  260. data/ruby/neo4j/driver/transaction_config.rb +50 -0
  261. data/ruby/neo4j/driver/values.rb +26 -0
  262. data/{lib → ruby}/neo4j/driver/version.rb +1 -1
  263. data/ruby/neo4j/driver.rb +29 -0
  264. metadata +264 -101
  265. data/ffi/bolt/address.rb +0 -11
  266. data/ffi/bolt/address_resolver.rb +0 -12
  267. data/ffi/bolt/address_set.rb +0 -9
  268. data/ffi/bolt/auth.rb +0 -10
  269. data/ffi/bolt/auto_releasable.rb +0 -22
  270. data/ffi/bolt/boolean.rb +0 -9
  271. data/ffi/bolt/bytes.rb +0 -10
  272. data/ffi/bolt/config.rb +0 -45
  273. data/ffi/bolt/connection.rb +0 -44
  274. data/ffi/bolt/connector.rb +0 -17
  275. data/ffi/bolt/dictionary.rb +0 -15
  276. data/ffi/bolt/error.rb +0 -74
  277. data/ffi/bolt/float.rb +0 -9
  278. data/ffi/bolt/integer.rb +0 -9
  279. data/ffi/bolt/library.rb +0 -12
  280. data/ffi/bolt/lifecycle.rb +0 -9
  281. data/ffi/bolt/list.rb +0 -10
  282. data/ffi/bolt/log.rb +0 -16
  283. data/ffi/bolt/socket_options.rb +0 -14
  284. data/ffi/bolt/status.rb +0 -25
  285. data/ffi/bolt/string.rb +0 -9
  286. data/ffi/bolt/structure.rb +0 -10
  287. data/ffi/bolt/value.rb +0 -35
  288. data/ffi/neo4j/driver/auth_tokens.rb +0 -18
  289. data/ffi/neo4j/driver/config.rb +0 -40
  290. data/ffi/neo4j/driver/graph_database.rb +0 -52
  291. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
  292. data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
  293. data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
  294. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
  295. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
  296. data/ffi/neo4j/driver/internal/driver_factory.rb +0 -125
  297. data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
  298. data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
  299. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
  300. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
  301. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
  302. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
  303. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
  304. data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
  305. data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
  306. data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
  307. data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
  308. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
  309. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
  310. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
  311. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
  312. data/ffi/neo4j/driver/internal/network_session.rb +0 -129
  313. data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
  314. data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
  315. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
  316. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
  317. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
  318. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
  319. data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
  320. data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
  321. data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
  322. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
  323. data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
  324. data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
  325. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
  326. data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
  327. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
  328. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
  329. data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
  330. data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
  331. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
  332. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
  333. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
  334. data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
  335. data/ffi/neo4j/driver/net/server_address.rb +0 -13
  336. data/ffi/neo4j/driver/statement.rb +0 -15
  337. data/ffi/neo4j/driver/types/entity.rb +0 -21
  338. data/ffi/neo4j/driver/types/node.rb +0 -16
  339. data/ffi/neo4j/driver/types/path.rb +0 -35
  340. data/ffi/neo4j/driver/types/relationship.rb +0 -19
  341. data/ffi/neo4j/driver.rb +0 -61
  342. data/lib/neo4j/driver/internal/ruby_signature.rb +0 -18
@@ -0,0 +1,168 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ module Pulln
5
+ class AutoPullResponseHandler < BasicPullResponseHandler
6
+ delegate :signal, to: :@records
7
+ LONG_MAX_VALUE = 2 ** 63 - 1
8
+
9
+ def initialize(query, run_response_handler, connection, metadata_extractor, completion_listener, fetch_size)
10
+ super(query, run_response_handler, connection, metadata_extractor, completion_listener)
11
+ @fetch_size = fetch_size
12
+
13
+ # For pull everything ensure conditions for disabling auto pull are never met
14
+ if fetch_size == FetchSizeUtil::UNLIMITED_FETCH_SIZE
15
+ @high_record_watermark = LONG_MAX_VALUE
16
+ @low_record_watermark = LONG_MAX_VALUE
17
+ else
18
+ @high_record_watermark = fetch_size * 0.7
19
+ @low_record_watermark = fetch_size * 0.3
20
+ end
21
+
22
+ @records = ::Async::Queue.new
23
+ @auto_pull_enabled = true
24
+
25
+ install_record_and_summary_consumers
26
+ end
27
+
28
+ private def install_record_and_summary_consumers
29
+ install_record_consumer do |record, error|
30
+ if record
31
+ enqueue_record(record)
32
+ complete_record_future(record)
33
+ end
34
+
35
+ # if !error.nil? Handled by summary.error already
36
+ if record.nil? && error.nil?
37
+ # complete
38
+ complete_record_future(nil)
39
+ end
40
+ end
41
+
42
+ install_summary_consumer do |summary, error|
43
+ handle_failure(error) if error
44
+
45
+ if summary
46
+ @summary = summary
47
+ complete_summary_future(summary)
48
+ end
49
+
50
+ if error.nil? && summary.nil? # has_more
51
+ request(@fetch_size) if @auto_pull_enabled
52
+ end
53
+ end
54
+ end
55
+
56
+ private def handle_failure(error)
57
+ # error has not been propagated to the user, remember it
58
+ unless fail_record_future(error) || fail_summary_future(error)
59
+ @failure = error
60
+ end
61
+ end
62
+
63
+ def peek_async
64
+ while @records.empty? && !done?
65
+ @records.wait
66
+ end
67
+ @records.items.first&.then(&Util::ResultHolder.method(:successful)) or
68
+ completed_with_value_if_no_failure(nil)
69
+ end
70
+
71
+ def next_async
72
+ peek_async.then { |record| dequeue_record if record }
73
+ end
74
+
75
+ def consume_async
76
+ @records.items.clear
77
+ cancel unless done?
78
+ completed_with_value_if_no_failure(@summary)
79
+ end
80
+
81
+ def list_async(&block)
82
+ pull_all_async.then do
83
+ unless done?
84
+ raise Exceptions::IllegalStateException, "Can't get records as list because SUCCESS or FAILURE did not arrive"
85
+ end
86
+ @records.items.map(&block)
87
+ ensure
88
+ @records.items.clear
89
+ end
90
+ end
91
+
92
+ def pull_all_failure_async
93
+ pull_all_async.chain { |_, error| error }
94
+ end
95
+
96
+ def pre_populate_records
97
+ request(@fetch_size)
98
+ end
99
+
100
+ private
101
+
102
+ def pull_all_async
103
+ return completed_with_value_if_no_failure(@summary) if done?
104
+ (@summary_future ||= Util::ResultHolder.new).tap do |_|
105
+ request(FetchSizeUtil::UNLIMITED_FETCH_SIZE)
106
+ end
107
+ end
108
+
109
+ def enqueue_record(record)
110
+ @records << record
111
+
112
+ # too many records in the queue, pause auto request gathering
113
+ @auto_pull_enabled = false if @records.size > @high_record_watermark
114
+ end
115
+
116
+ def dequeue_record
117
+ record = @records.dequeue
118
+
119
+ if @records.size <= @low_record_watermark
120
+ # if not in streaming state we need to restart streaming
121
+ request(@fetch_size) if state != State::STREAMING_STATE
122
+
123
+ @auto_pull_enabled = true
124
+ end
125
+
126
+ record
127
+ end
128
+
129
+ def extract_failure
130
+ @failure or raise Exceptions::IllegalStateException, "Can't extract failure because it does not exist"
131
+ ensure
132
+ @failure = nil # propagate failure only once
133
+ end
134
+
135
+ def complete_record_future(record)
136
+ @record_future&.succeed(record)
137
+ @record_future = nil
138
+ end
139
+
140
+ def complete_summary_future(summary)
141
+ @summary_future&.succeed(summary)
142
+ @summary_future = nil
143
+ end
144
+
145
+ def fail_record_future(error)
146
+ @record_future&.fail(error)
147
+ ensure
148
+ @record_future = nil
149
+ end
150
+
151
+ def fail_summary_future(error)
152
+ @summary_future&.fail(error)
153
+ ensure
154
+ @summary_future = nil
155
+ end
156
+
157
+ def completed_with_value_if_no_failure(value)
158
+ if @failure
159
+ Util::ResultHolder.failed(extract_failure)
160
+ else
161
+ Util::ResultHolder.successful(value)
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,298 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ module Pulln
5
+ class BasicPullResponseHandler
6
+ include Spi::ResponseHandler
7
+ attr :state
8
+
9
+ def initialize(query, run_response_handler, connection, metadata_extractor, completion_listener)
10
+ super()
11
+ @query = Validator.require_non_nil!(query)
12
+ @run_response_handler = Validator.require_non_nil!(run_response_handler)
13
+ @metadata_extractor = Validator.require_non_nil!(metadata_extractor)
14
+ @connection = Validator.require_non_nil!(connection)
15
+ @completion_listener = Validator.require_non_nil!(completion_listener)
16
+ @state = State::READY_STATE
17
+ @to_request = 0
18
+ end
19
+
20
+ def state=(state)
21
+ @state = state
22
+ signal
23
+ end
24
+
25
+ def on_success(metadata)
26
+ assert_record_and_summary_consumer_installed
27
+ @state.on_success(self, metadata)
28
+ end
29
+
30
+ def on_failure(error)
31
+ assert_record_and_summary_consumer_installed
32
+ @state.on_failure(self, error)
33
+ end
34
+
35
+ def on_record(fields)
36
+ assert_record_and_summary_consumer_installed
37
+ @state.on_record(self, fields)
38
+ end
39
+
40
+ def request(size)
41
+ assert_record_and_summary_consumer_installed
42
+ @state.request(self, size)
43
+ end
44
+
45
+ def cancel
46
+ assert_record_and_summary_consumer_installed
47
+ @state.cancel(self)
48
+ end
49
+
50
+ def complete_with_failure(error)
51
+ @completion_listener.after_failure(error)
52
+ complete(extract_result_summary, error)
53
+ end
54
+
55
+ def complete_with_success(metadata)
56
+ @completion_listener.after_success(metadata)
57
+ summary, exception =
58
+ begin
59
+ [extract_result_summary(**metadata), nil]
60
+ rescue Exceptions::Neo4jException => e
61
+ [extract_result_summary, e]
62
+ end
63
+ complete(summary, exception)
64
+ end
65
+
66
+ def success_has_more
67
+ if @to_request > 0 || @to_request == FetchSizeUtil::UNLIMITED_FETCH_SIZE
68
+ request(@to_request)
69
+ @to_request = 0
70
+ end
71
+
72
+ # summary consumer use (null, null) to identify done handling of success with has_more
73
+ @summary_consumer.call(nil, nil)
74
+ end
75
+
76
+ def handle_record(fields)
77
+ record = InternalRecord.new(@run_response_handler.query_keys, fields)
78
+ @record_consumer.call(record, nil)
79
+ end
80
+
81
+ def write_pull(n)
82
+ @connection.write_and_flush(Messaging::Request::PullMessage.new(n, @run_response_handler.query_id), self)
83
+ end
84
+
85
+ def discard_all
86
+ @connection.write_and_flush(Messaging::Request::DiscardMessage.new_discard_all_message(@run_response_handler.query_id), self)
87
+ end
88
+
89
+ def install_summary_consumer(&summary_consumer)
90
+ raise Exceptions::IllegalStateException, 'Summary consumer already installed.' if @summary_consumer
91
+
92
+ @summary_consumer = summary_consumer
93
+ end
94
+
95
+ def install_record_consumer(&record_consumer)
96
+ raise Exceptions::IllegalStateException, 'Record consumer already installed.' if @record_consumer
97
+
98
+ @record_consumer = record_consumer
99
+ end
100
+
101
+ def done?
102
+ @state == State::SUCCEEDED_STATE || @state == State::FAILURE_STATE
103
+ end
104
+
105
+ private def extract_result_summary(**metadata)
106
+ result_available_after = @run_response_handler.result_available_after
107
+ @metadata_extractor.extract_summary(@query, @connection, result_available_after, metadata)
108
+ end
109
+
110
+ private def add_to_request(to_add)
111
+ return if @to_request == FetchSizeUtil::UNLIMITED_FETCH_SIZE
112
+
113
+ # pull all
114
+ return @to_request = FetchSizeUtil::UNLIMITED_FETCH_SIZE if to_add == FetchSizeUtil::UNLIMITED_FETCH_SIZE
115
+
116
+ if to_add <= 0
117
+ raise ArgumentError, "Cannot request record amount that is less than or equal to 0. Request amount: #{to_add}"
118
+ end
119
+
120
+ @to_request += to_add
121
+
122
+ # to_add is already at least 1, we hit buffer overflow
123
+ @to_request = [@to_request, LONG_MAX_VALUE].min
124
+ end
125
+
126
+ private def assert_record_and_summary_consumer_installed
127
+ # no need to check if we've finished.
128
+ return if done?
129
+
130
+ if @record_consumer.nil? || @summary_consumer.nil?
131
+ raise Exceptions::IllegalStateException, "Access record stream without record consumer and/or summary consumer. Record consumer=#{@record_consumer}, Summary consumer=#{@summary_consumer}"
132
+ end
133
+ end
134
+
135
+ private def complete(summary, error)
136
+ # we first inform the summary consumer to ensure when streaming finished, summary is definitely available.
137
+ @summary_consumer.call(summary, error)
138
+ # record consumer use (nil, nil) to identify the end of record stream
139
+ @record_consumer.call(nil, error)
140
+ dispose
141
+ end
142
+
143
+ private def dispose
144
+ # release the reference to the consumers who hold the reference to subscribers which shall be released when subscription is completed.
145
+ @record_consumer = nil
146
+ @summary_consumer = nil
147
+ end
148
+
149
+ module State
150
+ class Ready
151
+ def on_success(context, metadata)
152
+ context.state = SUCCEEDED_STATE
153
+ context.complete_with_success(metadata)
154
+ end
155
+
156
+ def on_failure(context, error)
157
+ context.state = FAILURE_STATE
158
+ context.complete_with_failure(error)
159
+ end
160
+
161
+ def on_record(context, _fields)
162
+ context.state = READY_STATE
163
+ end
164
+
165
+ def request(context, n)
166
+ context.state = STREAMING_STATE
167
+ context.write_pull(n)
168
+ end
169
+
170
+ def cancel(context)
171
+ context.state = CANCELLED_STATE
172
+ context.discard_all
173
+ end
174
+ end
175
+
176
+ READY_STATE = Ready.new
177
+
178
+ class Streaming
179
+ def on_success(context, metadata)
180
+ if metadata[:has_more]
181
+ context.state = READY_STATE
182
+ context.success_has_more
183
+ else
184
+ context.state = SUCCEEDED_STATE
185
+ context.complete_with_success(metadata)
186
+ end
187
+ end
188
+
189
+ def on_failure(context, error)
190
+ context.state = FAILURE_STATE
191
+ context.complete_with_failure(error)
192
+ end
193
+
194
+ def on_record(context, fields)
195
+ context.state = STREAMING_STATE
196
+ context.handle_record(fields)
197
+ end
198
+
199
+ def request(context, n)
200
+ context.state = STREAMING_STATE
201
+ context.add_to_request(n)
202
+ end
203
+
204
+ def cancel(context)
205
+ context.state = CANCELLED_STATE
206
+ end
207
+ end
208
+
209
+ STREAMING_STATE = Streaming.new
210
+
211
+ class Cancelled
212
+ def on_success(context, metadata)
213
+ if metadata[:has_more]
214
+ context.state = CANCELLED_STATE
215
+ context.discard_all
216
+ else
217
+ context.state = SUCCEEDED_STATE
218
+ context.complete_with_success(metadata)
219
+ end
220
+ end
221
+
222
+ def on_failure(context, error)
223
+ context.state = FAILURE_STATE
224
+ context.complete_with_failure(error)
225
+ end
226
+
227
+ def on_record(context, _fields)
228
+ context.state = CANCELLED_STATE
229
+ end
230
+
231
+ def request(context, _n)
232
+ context.state = CANCELLED_STATE
233
+ end
234
+
235
+ def cancel(context)
236
+ context.state = CANCELLED_STATE
237
+ end
238
+ end
239
+
240
+ CANCELLED_STATE = Cancelled.new
241
+
242
+ class Succeeded
243
+ def on_success(context, metadata)
244
+ context.state = SUCCEEDED_STATE
245
+ context.complete_with_success(metadata)
246
+ end
247
+
248
+ def on_failure(context, error)
249
+ context.state = FAILURE_STATE
250
+ context.complete_with_failure(error)
251
+ end
252
+
253
+ def on_record(context, _fields)
254
+ context.state = SUCCEEDED_STATE
255
+ end
256
+
257
+ def request(context, _n)
258
+ context.state = SUCCEEDED_STATE
259
+ end
260
+
261
+ def cancel(context)
262
+ context.state = SUCCEEDED_STATE
263
+ end
264
+ end
265
+
266
+ SUCCEEDED_STATE = Succeeded.new
267
+
268
+ class Failed
269
+ def on_success(context, metadata)
270
+ context.state = SUCCEEDED_STATE
271
+ context.complete_with_success(metadata)
272
+ end
273
+
274
+ def on_failure(context, error)
275
+ context.state = FAILURE_STATE
276
+ context.complete_with_failure(error)
277
+ end
278
+
279
+ def on_record(context, _fields)
280
+ context.state = FAILURE_STATE
281
+ end
282
+
283
+ def request(context, _n)
284
+ context.state = FAILURE_STATE
285
+ end
286
+
287
+ def cancel(context)
288
+ context.state = FAILURE_STATE
289
+ end
290
+ end
291
+
292
+ FAILURE_STATE = Failed.new
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,20 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ module Pulln
5
+ class FetchSizeUtil
6
+ UNLIMITED_FETCH_SIZE = -1
7
+ DEFAULT_FETCH_SIZE = 1000
8
+
9
+ def self.assert_valid_fetch_size(size)
10
+ if size <= 0 && size != UNLIMITED_FETCH_SIZE
11
+ raise ArgumentError, "The record fetch size may not be 0 or negative. Illegal record fetch size: #{size}."
12
+ end
13
+
14
+ size
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ class ResetResponseHandler
5
+ include Spi::ResponseHandler
6
+
7
+ def initialize(message_dispatcher, completion_future = nil)
8
+ @message_dispatcher = message_dispatcher
9
+ @completion_future = completion_future
10
+ end
11
+
12
+ def on_success(_metadata = {})
13
+ reset_completed(true)
14
+ end
15
+
16
+ def on_failure(_error)
17
+ reset_completed(false)
18
+ end
19
+
20
+ def on_record(_fields)
21
+ raise java.lang.UnsupportedOperationException
22
+ end
23
+
24
+ private def reset_completed(_success)
25
+ @message_dispatcher.clear_current_error
26
+
27
+ unless @completion_future.nil?
28
+ @completion_future.complete(nil)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ class RollbackTxResponseHandler
5
+ include Spi::ResponseHandler
6
+
7
+ def initialize(result_holder)
8
+ @result_holder = result_holder
9
+ end
10
+
11
+ def on_success(_metadata)
12
+ @result_holder.succeed
13
+ end
14
+
15
+ def on_failure(error)
16
+ @result_holder.fail(error)
17
+ end
18
+
19
+ def on_record(fields)
20
+ raise "Transaction rollback is not expected to receive records: #{fields}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ class RouteMessageResponseHandler < Struct.new(:completion_listener)
5
+ include Spi::ResponseHandler
6
+
7
+ def on_success(metadata)
8
+ completion_listener.routing_table = metadata[:rt]
9
+ end
10
+
11
+ def on_failure(error)
12
+ raise error
13
+ end
14
+
15
+ def on_record(fields)
16
+ raise "Route is not expected to receive records: #{fields}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,70 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ class RoutingResponseHandler
5
+ include Spi::ResponseHandler
6
+ delegate :on_success, :on_record, :can_manage_auto_read, :disable_auto_read_management, to: :@delegate
7
+
8
+ def initialize(delegate, address, access_mode, error_handler)
9
+ @delegate = delegate
10
+ @address = address
11
+ @access_mode = access_mode
12
+ @error_handler = error_handler
13
+ end
14
+
15
+ def on_failure(error)
16
+ new_error = handled_error(error)
17
+ @delegate.on_failure(new_error)
18
+ end
19
+
20
+ private
21
+
22
+ def handled_error(received_error)
23
+ # TODO: probably not necessary with concurrent-ruby as it might not wrap exceptions like java
24
+ error = Futures.completion_exception_cause(received_error)
25
+
26
+ case error
27
+ when Exceptions::ServiceUnavailableException
28
+ handled_service_unavailable_exception(error)
29
+ when Exceptions::ClientException
30
+ handled_client_exception(error)
31
+ when Exceptions::TransientException
32
+ handled_transient_exception(error)
33
+ else
34
+ error
35
+ end
36
+ end
37
+
38
+ def handled_service_unavailable_exception(e)
39
+ @error_handler.on_connection_failure(@address)
40
+ Exceptions::SessionExpiredException("Server at #{@address} is no longer available", e)
41
+ end
42
+
43
+ def handled_transient_exception(e)
44
+ e.code == "Neo.TransientError.General.DatabaseUnavailable" ? error_handler.on_connection_failure(@address) : e
45
+ end
46
+
47
+ def handled_client_exception(e)
48
+ return e unless failure_to_write?(e)
49
+
50
+ # The server is unaware of the session mode, so we have to implement this logic in the driver.
51
+ # In the future, we might be able to move this logic to the server.
52
+ case @access_mode
53
+ when AccessMode::READ
54
+ Exceptions::ClientException.new('Write queries cannot be performed in READ access mode.')
55
+ when AccessMode::WRITE
56
+ @error_handler.on_write_failure(@address)
57
+ Exceptions::SessionExpiredException.new('Server at %s no longer accepts writes' % @address)
58
+ else
59
+ raise ArgumentError, @accessMode + ' not supported.'
60
+ end
61
+ end
62
+
63
+ def failure_to_write?(e)
64
+ %w[Neo.ClientError.Cluster.NotALeader
65
+ Neo.ClientError.General.ForbiddenOnReadOnlyDatabase].include?(e.code)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Handlers
4
+ class RunResponseHandler
5
+ include Spi::ResponseHandler
6
+ attr :query_keys, :result_available_after, :query_id, :error
7
+
8
+ def initialize(metadata_extractor, connection, tx)
9
+ @query_keys = []
10
+ @metadata_extractor = metadata_extractor
11
+ @connection = connection
12
+ @tx = tx
13
+ end
14
+
15
+ def on_success(metadata)
16
+ @query_keys = @metadata_extractor.extract_query_keys(metadata)
17
+ @result_available_after = @metadata_extractor.extract_result_available_after(metadata)
18
+ @query_id = @metadata_extractor.extract_query_id(metadata)
19
+ end
20
+
21
+ def on_failure(error)
22
+ if @tx
23
+ @tx.mark_terminated(error)
24
+ elsif error.is_a?(Exceptions::AuthorizationExpiredException)
25
+ connection.terminate_and_release(Exceptions::AuthorizationExpiredException::DESCRIPTION)
26
+ elsif error.is_a?(Exceptions::ConnectionReadTimeoutException)
27
+ connection.terminate_and_release(error.message)
28
+ end
29
+ @error = error
30
+ end
31
+
32
+ def on_record(_fields)
33
+ raise 'unsupported operation'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end