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,95 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class RoutingTableHandlerImpl
5
+ attr_reader :routing_table
6
+
7
+ delegate :servers, to: :routing_table
8
+
9
+ def initialize(routing_table, rediscovery, connection_pool, routing_table_registry, logger, routing_table_purge_delay)
10
+ @routing_table = routing_table
11
+ @database_name = routing_table.database
12
+ @rediscovery = rediscovery
13
+ @connection_pool = connection_pool
14
+ @routing_table_registry = routing_table_registry
15
+ @log = logger
16
+ @routing_table_purge_delay = routing_table_purge_delay
17
+ @mutex = Concurrent::ReentrantReadWriteLock.new
18
+ end
19
+
20
+ def on_connection_failure(address)
21
+ # remove server from the routing table, to prevent concurrent threads from making connections to this address
22
+ @routing_table.forget(address)
23
+ end
24
+
25
+ def on_write_failure(address)
26
+ @routing_table.forget_writer(address)
27
+ end
28
+
29
+ def ensure_routing_table(context)
30
+ @mutex.with_write_lock do
31
+ if @routing_table.stale_for?(context.mode)
32
+ # existing routing table is not fresh and should be updated
33
+ @log.debug("Routing table for database '#{@database_name.description}' is stale. #{@routing_table}")
34
+
35
+ fresh_cluster_composition_fetched(
36
+ @rediscovery.lookup_cluster_composition(@routing_table, @connection_pool, context.rediscovery_bookmark,
37
+ nil))
38
+ else
39
+ # existing routing table is fresh, use it
40
+ @routing_table
41
+ end
42
+ rescue => error
43
+ cluster_composition_lookup_failed(error)
44
+ end
45
+ end
46
+
47
+ def update_routing_table(composition_lookup_result)
48
+ @mutex.with_write_lock do
49
+ if composition_lookup_result.cluster_composition.expiration_timestamp < @routing_table.expiration_timestamp
50
+ @routing_table
51
+ else
52
+ fresh_cluster_composition_fetched(composition_lookup_result)
53
+ end
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def fresh_cluster_composition_fetched(composition_lookup_result)
60
+ @log.debug("Fetched cluster composition for database '#{@database_name.description}'. #{composition_lookup_result.cluster_composition}")
61
+ @routing_table.update(composition_lookup_result.cluster_composition)
62
+ @routing_table_registry.remove_aged
63
+ addresses_to_retain = @routing_table_registry.all_servers.map(&:unicast_stream).reduce(&:+)
64
+
65
+ composition_lookup_result.resolved_initial_routers&.then do |addresses|
66
+ addresses_to_retain << addresses
67
+ end
68
+
69
+ @connection_pool.retain_all(addresses_to_retain)
70
+
71
+ @log.debug("Updated routing table for database '#{@database_name.description}'. #{routing_table}")
72
+ @routing_table
73
+ rescue => error
74
+ cluster_composition_lookup_failed(error)
75
+ end
76
+
77
+ def cluster_composition_lookup_failed(error)
78
+ @log.error do
79
+ "Failed to update routing table for database '#{@database_name.description}'. Current routing table: #{@routing_table}."
80
+ end
81
+ @log.error(error)
82
+ @routing_table_registry.remove(@database_name)
83
+ raise error
84
+ end
85
+
86
+ public
87
+
88
+ # This method cannot be synchronized as it will be visited by all routing table handler's threads concurrently
89
+ def routing_table_aged?
90
+ @mutex.with_read_lock { @routing_table.has_been_stale_for?(@routing_table_purge_delay) }
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,121 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class RoutingTableRegistryImpl
5
+ def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
6
+ @factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
7
+ @routing_table_handlers = Concurrent::Map.new
8
+ @principal_to_database_name = {}
9
+ @clock = clock
10
+ @connection_pool = connection_pool
11
+ @rediscovery = rediscovery
12
+ @log = logger
13
+ @mutex = Mutex.new
14
+ end
15
+
16
+ def ensure_routing_table(context)
17
+ ctx_and_handler = ensure_database_name_is_completed(context)
18
+ (ctx_and_handler.handler || get_or_create(context.database_name))
19
+ .tap { |handler| handler.ensure_routing_table(ctx_and_handler.context) }
20
+ end
21
+
22
+ private def ensure_database_name_is_completed(context)
23
+ context_database_name = context.database_name
24
+
25
+ return ConnectionContextAndHandler.new(context, nil) if context_database_name
26
+ @mutex.synchronize do
27
+ return ConnectionContextAndHandler.new(context, nil) if context_database_name
28
+
29
+ impersonated_user = context.impersonated_user
30
+ principal = Principal.new(impersonated_user)
31
+ database_name = @principal_to_database_name[principal]
32
+ handler_ref = Concurrent::AtomicReference.new
33
+
34
+ if database_name.nil?
35
+ @principal_to_database_name[principal] = database_name
36
+
37
+ routing_table = ClusterRoutingTable.new(DatabaseNameUtil.default_database, @clock)
38
+
39
+ composition_lookup_result = @rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, impersonated_user)
40
+ database_name = DatabaseNameUtil.database(composition_lookup_result.cluster_composition.database_name)
41
+ handler = get_or_create(database_name)
42
+ handler_ref.set(handler)
43
+ handler.update_routing_table(composition_lookup_result)
44
+ @principal_to_database_name.delete(principal)
45
+ end
46
+
47
+ context.database_name = database_name
48
+ ConnectionContextAndHandler.new(context, handler_ref.get)
49
+ end
50
+ end
51
+
52
+ def all_servers
53
+ # obviously we just had a snapshot of all servers in all routing tables
54
+ # after we read it, the set could already be changed.
55
+ @routing_table_handlers.values.map(&:servers).reduce(&:+)
56
+ end
57
+
58
+ def remove(database_name)
59
+ @routing_table_handlers.delete(database_name)
60
+ @log.debug("Routing table handler for database '#{database_name.description}' is removed.")
61
+ end
62
+
63
+ def remove_aged
64
+ @routing_table_handlers.each do |database_name, handler|
65
+ if handler.routing_table_aged?
66
+ @log.info("Routing table handler for database '#{database_name.description}' is removed because it has not been used for a long time. Routing table: #{handler.routing_table}")
67
+ @routing_table_handlers.delete(database_name)
68
+ end
69
+ end
70
+ end
71
+
72
+ def routing_table_handler(database_name)
73
+ database_name = DatabaseNameUtil.database(database_name) unless database_name.is_a?(InternalDatabaseName)
74
+ @routing_table_handlers[database_name]
75
+ end
76
+
77
+ # For tests
78
+ delegate :key?, to: :@routing_table_handlers
79
+
80
+ def get_or_create(database_name)
81
+ @routing_table_handlers.compute_if_absent(database_name) do
82
+ # TODO: Verify if applies
83
+ # Note: Atomic methods taking a block do not allow the self instance to be used within the block. Doing so will cause a deadlock.
84
+ handler = @factory.new_instance(database_name, self)
85
+ @log.debug("Routing table handler for database '#{database_name.description}' is added.")
86
+ handler
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ class RoutingTableHandlerFactory
93
+ def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
94
+ @connection_pool = connection_pool
95
+ @rediscovery = rediscovery
96
+ @clock = clock
97
+ @logger = logger
98
+ @routing_table_purge_delay = routing_table_purge_delay
99
+ end
100
+
101
+ def new_instance(database_name, all_tables)
102
+ routing_table = ClusterRoutingTable.new(database_name, @clock)
103
+ RoutingTableHandlerImpl.new(routing_table, @rediscovery, @connection_pool, all_tables, @logger, @routing_table_purge_delay)
104
+ end
105
+ end
106
+
107
+ class Principal < Struct.new(:id)
108
+ end
109
+
110
+ class ConnectionContextAndHandler
111
+ attr_reader :context, :handler
112
+
113
+ def initialize(context, handler)
114
+ @context = context
115
+ @handler = handler
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,73 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+
5
+ # This implementation of the {@link RoutingProcedureRunner} works with single database versions of Neo4j calling
6
+ # the procedure `dbms.cluster.routing.getRoutingTable`
7
+ class SingleDatabaseRoutingProcedureRunner
8
+ ROUTING_CONTEXT = :context
9
+ GET_ROUTING_TABLE = "CALL dbms.cluster.routing.getRoutingTable($#{ROUTING_CONTEXT})"
10
+
11
+ def initialize(context)
12
+ @context = context
13
+ end
14
+
15
+ def run(connection, database_name, bookmark, impersonated_user)
16
+ delegate = connection(connection)
17
+ procedure = procedure_query(connection.server_version, database_name)
18
+ bookmark_holder = bookmark_holder(bookmark)
19
+ begin
20
+ result = run_procedure(delegate, procedure, bookmark_holder)
21
+ RoutingProcedureResponse.new(procedure, **result.error ? { error: result.error } : { records: result.result! })
22
+ rescue => error
23
+ handle_error(procedure, error)
24
+ ensure
25
+ release_connection(delegate)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def connection(connection)
32
+ Async::Connection::DirectConnection.new(connection, DatabaseNameUtil.default_database, AccessMode::WRITE, nil)
33
+ end
34
+
35
+ def procedure_query(server_version, database_name)
36
+ if database_name.database_name.present?
37
+ raise Exceptions::FatalDiscoveryException, "Refreshing routing table for multi-databases is not supported in server version lower than 4.0. Current server version: #{server_version}. Database name: '#{database_name.description}'"
38
+ end
39
+
40
+ Query.new(GET_ROUTING_TABLE, ROUTING_CONTEXT => @context.to_h)
41
+ end
42
+
43
+ def bookmark_holder(_ignored)
44
+ BookmarkHolder::NO_OP
45
+ end
46
+
47
+ def run_procedure(connection, procedure, bookmark_holder)
48
+ connection.protocol
49
+ .run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
50
+ Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
51
+ .async_result.list_async
52
+ end
53
+
54
+ def release_connection(connection)
55
+ # It is not strictly required to release connection after routing procedure invocation because it'll
56
+ # be released by the PULL_ALL response handler after result is fully fetched. Such release will happen
57
+ # in background. However, releasing it early as part of whole chain makes it easier to reason about
58
+ # rediscovery in stub server tests. Some of them assume connections to instances not present in new
59
+ # routing table will be closed immediately.
60
+ connection.release
61
+ end
62
+
63
+ def handle_error(procedure, error)
64
+ if error.is_a? Exceptions::ClientException
65
+ RoutingProcedureResponse.new(procedure, error: error)
66
+ else
67
+ raise error
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,16 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+
4
+ # The connection settings are used whenever a new connection is
5
+ # established to a server, specifically as part of the INIT request.
6
+ class ConnectionSettings
7
+ attr_reader :auth_token, :user_agent, :connect_timeout_millis
8
+
9
+ def initialize(auth_token, user_agent, connect_timeout_millis)
10
+ @auth_token = auth_token
11
+ @user_agent = user_agent
12
+ @connect_timeout_millis = connect_timeout_millis
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,55 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ class AsyncResultCursorImpl
5
+ delegate :consume_async, :next_async, :peek_async, to: :@pull_all_handler
6
+
7
+ def initialize(run_handler, pull_all_handler)
8
+ @run_handler = run_handler
9
+ @pull_all_handler = pull_all_handler
10
+ end
11
+
12
+ def keys
13
+ @run_handler.query_keys
14
+ end
15
+
16
+ def single_async
17
+ next_async.compose do |first_record|
18
+ unless first_record
19
+ raise Exceptions::NoSuchRecordException, 'Cannot retrieve a single record, because this result is empty.'
20
+ end
21
+ next_async.then do |second_record|
22
+ if second_record
23
+ raise Exceptions::NoSuchRecordException,
24
+ 'Expected a result with a single record, but this result contains at least one more. Ensure your query returns only one record.'
25
+ end
26
+ first_record
27
+ end
28
+ end
29
+ end
30
+
31
+ def list_async(&map_function)
32
+ @pull_all_handler.list_async(&block_given? ? map_function : :itself)
33
+ end
34
+
35
+ def discard_all_failure_async
36
+ # runError has priority over other errors and is expected to have been reported to user by now
37
+ consume_async.error.then { |error| run_error ? nil : error }
38
+ end
39
+
40
+ def pull_all_failure_async
41
+ # runError has priority over other errors and is expected to have been reported to user by now
42
+ @pull_all_handler.pull_all_failure_async.then { |error| run_error ? nil : error }
43
+ end
44
+
45
+ def map_successful_run_completion_async
46
+ run_error&.then(&Util::ResultHolder.method(:failed)) || Util::ResultHolder.successful(self)
47
+ end
48
+
49
+ def run_error
50
+ @run_handler.error
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ # Used by Bolt V1, V2, V3
5
+ class AsyncResultCursorOnlyFactory
6
+ def initialize(connection, run_message, run_handler, pull_handler)
7
+ @connection = Internal::Validator.require_non_nil!(connection)
8
+ @run_message = Internal::Validator.require_non_nil!(run_message)
9
+ @run_handler = Internal::Validator.require_non_nil!(run_handler)
10
+
11
+ @pull_all_handler = Internal::Validator.require_non_nil!(pull_handler)
12
+ end
13
+
14
+ def async_result
15
+ # only write and flush messages when async result is wanted.
16
+ @connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
17
+ @pull_all_handler.pre_populate_records
18
+
19
+ DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,61 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ class DisposableAsyncResultCursor
5
+ include Enumerable
6
+ delegate :keys, :pull_all_failure_async, to: :@delegate
7
+
8
+ def initialize(delegate)
9
+ @delegate = delegate
10
+ end
11
+
12
+ def consume_async
13
+ @disposed = true
14
+ @delegate.consume_async
15
+ end
16
+
17
+ def next_async
18
+ assert_not_disposed
19
+ @delegate.next_async
20
+ end
21
+
22
+ def peek_async
23
+ assert_not_disposed
24
+ @delegate.peek_async
25
+ end
26
+
27
+ def single_async
28
+ assert_not_disposed
29
+ @delegate.single_async
30
+ end
31
+
32
+ def each(&action)
33
+ assert_not_disposed
34
+ @delegate.each(&action)
35
+ end
36
+
37
+ def list_async(&block)
38
+ assert_not_disposed
39
+ @delegate.list_async(&block)
40
+ end
41
+
42
+ def discard_all_failure_async
43
+ @disposed = true
44
+ @delegate.discard_all_failure_async
45
+ end
46
+
47
+ private def assert_not_disposed
48
+ raise Util::ErrorUtil.new_result_consumed_error if @disposed
49
+ end
50
+
51
+ def disposed?
52
+ @disposed
53
+ end
54
+
55
+ def map_successful_run_completion_async
56
+ @delegate.map_successful_run_completion_async.then { self }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,24 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ # Bolt V4
5
+ class ResultCursorFactoryImpl
6
+ def initialize(connection, run_message, run_handler, pull_handler, pull_all_handler)
7
+ @connection = Internal::Validator.require_non_nil!(connection)
8
+ @run_message = Internal::Validator.require_non_nil!(run_message)
9
+ @run_handler = Internal::Validator.require_non_nil!(run_handler)
10
+ @pull_handler = Internal::Validator.require_non_nil!(pull_handler)
11
+ @pull_all_handler = Internal::Validator.require_non_nil!(pull_all_handler)
12
+ end
13
+
14
+ def async_result
15
+ # only write and flush messages when async result is wanted.
16
+ @connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
17
+ @pull_all_handler.pre_populate_records
18
+
19
+ DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,110 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ class RxResultCursorImpl
5
+ DISCARD_RECORD_CONSUMER = -> (record, throwable) {}
6
+
7
+ delegate :cancel, to: :@pull_handler
8
+ delegate :done?, to: :@summary_future
9
+
10
+ def initialize(run_error, run_handler, pull_handler)
11
+ java.util.Objects.require_non_null(run_handler)
12
+ java.util.Objects.require_non_null(pull_handler)
13
+
14
+ @run_response_error = run_error
15
+ @run_handler = @run_handler
16
+ @pull_handler = @pull_handler
17
+ @summary_future = java.util.concurrent.CompletableFuture.new
18
+ @consumer_status = RecordConsumerStatus::NOT_INSTALLED
19
+ install_summary_consumer
20
+ end
21
+
22
+ def keys
23
+ @run_handler.query_keys.keys
24
+ end
25
+
26
+ def install_record_consumer(record_consumer)
27
+ raise Util::ErrorUtil.new_result_consumed_error if result_consumed
28
+
29
+ return if @consumer_status.installed?
30
+
31
+ @consumer_status = record_consumer == DISCARD_RECORD_CONSUMER ? RecordConsumerStatus::DISCARD_INSTALLED : RecordConsumerStatus::INSTALLED
32
+ @pull_handler.install_record_consumer(record_consumer)
33
+ assert_run_completed_successfully
34
+ end
35
+
36
+ def request(n)
37
+ n = -1 if n == java.lang.Long::MAX_VALUE
38
+
39
+ @pull_handler.request(n)
40
+ end
41
+
42
+ def discard_all_failure_async
43
+ # calling this method will enforce discarding record stream and finish running cypher query
44
+ summary_stage.then_apply(-> (_summary) { nil }).exceptionally do |throwable|
45
+ @summary_future_exposed ? null : throwable
46
+ end
47
+ end
48
+
49
+ def pull_all_failure_async
50
+ if @consumer_status.installed? && !done?
51
+ return java.util.concurrent.CompletableFuture.completed_future(Exceptions::TransactionNestingException.new("You cannot run another query or begin a new transaction in the same session before you've fully consumed the previous run result."))
52
+ end
53
+
54
+ # It is safe to discard records as either the streaming has not started at all, or the streaming is fully finished.
55
+ discard_all_failure_async
56
+ end
57
+
58
+ def summary_async
59
+ @summary_future_exposed = true
60
+ summary_stage
61
+ end
62
+
63
+ def summary_stage
64
+ unless done? && @result_consumed # the summary is called before record streaming
65
+ install_record_consumer(DISCARD_RECORD_CONSUMER)
66
+ cancel
67
+ @result_consumed = true
68
+ end
69
+
70
+ @summary_future
71
+ end
72
+
73
+ private
74
+
75
+ def assert_run_completed_successfully
76
+ unless @run_response_error.nil?
77
+ @pull_handler.on_failure(@run_response_error)
78
+ end
79
+ end
80
+
81
+ def install_summary_consumer
82
+ @pull_handler.install_summary_consumer do |summary, error|
83
+ if !error.nil? && @consumer_status.discard_consumer?
84
+ # We will only report the error to summary if there is no user record consumer installed
85
+ # When a user record consumer is installed, the error will be reported to record consumer instead.
86
+ @summary_future.complete_exceptionally(error)
87
+ elsif !summary.nil?
88
+ @summary_future.complete(summary)
89
+ end
90
+
91
+ # else (nil, nil) to indicate a has_more success
92
+ end
93
+ end
94
+
95
+ class RecordConsumerStatus
96
+ attr_reader :installed, :discard_consumer
97
+
98
+ def initialize(installed, discard_consumer)
99
+ @installed = installed
100
+ @discard_consumer = discard_consumer
101
+ end
102
+
103
+ NOT_INSTALLED = new(false, false)
104
+ INSTALLED = new(true, false)
105
+ DISCARD_INSTALLED = new(true, true)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,37 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class DatabaseNameUtil
4
+ DEFAULT_DATABASE_NAME = nil
5
+ SYSTEM_DATABASE_NAME = 'system'
6
+
7
+ private
8
+
9
+ DEFAULT_DATABASE = InternalDatabaseName.new(description: '<default database>')
10
+ SYSTEM_DATABASE = InternalDatabaseName.new(database_name: SYSTEM_DATABASE_NAME)
11
+
12
+ public
13
+
14
+ class << self
15
+ def default_database
16
+ DEFAULT_DATABASE
17
+ end
18
+
19
+ def system_database
20
+ SYSTEM_DATABASE
21
+ end
22
+
23
+ def database(name)
24
+ case name
25
+ when DEFAULT_DATABASE_NAME
26
+ default_database
27
+ when SYSTEM_DATABASE_NAME
28
+ system_database
29
+ else
30
+ InternalDatabaseName.new(database_name: name)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,9 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class DefaultBookmarkHolder < ReadOnlyBookmarkHolder
4
+ def bookmark=(bookmark)
5
+ @bookmark = bookmark if bookmark.present?
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class DefaultDomainNameResolver
4
+ INSTANCE = new
5
+
6
+ def resolve(name)
7
+ java.net.InetAddress.get_all_by_name(name)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class DirectConnectionProvider
4
+ attr_reader :address
5
+
6
+ def initialize(address, connection_pool)
7
+ @address = address
8
+ @connection_pool = connection_pool
9
+ end
10
+
11
+ delegate :close, to: :@connection_pool
12
+
13
+ def acquire_connection(context)
14
+ database_name = context.database_name || DatabaseNameUtil::DEFAULT_DATABASE
15
+ Async::Connection::DirectConnection.new(private_acquire_connection, database_name, context.mode,
16
+ context.impersonated_user)
17
+ end
18
+
19
+ def verify_connectivity
20
+ private_acquire_connection&.release
21
+ end
22
+
23
+ def supports_multi_db?
24
+ private_acquire_connection.then do |conn|
25
+ Messaging::Request::MultiDatabaseUtil.supports_multi_database?(conn)
26
+ ensure
27
+ conn.release
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Used only for grabbing a connection with the server after hello message.
34
+ # This connection cannot be directly used for running any queries as it is missing necessary connection context
35
+ def private_acquire_connection
36
+ @connection_pool.acquire(@address)
37
+ end
38
+ end
39
+ end
40
+ end