neo4j-ruby-driver 1.7.5 → 4.4.0.alpha.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 (339) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -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_ruby_driver.rb +5 -10
  33. data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
  34. data/ruby/neo4j/driver/auth_tokens.rb +34 -0
  35. data/ruby/neo4j/driver/bookmark.rb +21 -0
  36. data/ruby/neo4j/driver/config.rb +91 -0
  37. data/ruby/neo4j/driver/graph_database.rb +140 -0
  38. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
  39. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
  40. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
  41. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
  42. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +77 -0
  43. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
  44. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
  45. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
  46. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
  47. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
  48. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
  49. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
  50. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
  51. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
  52. data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
  53. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
  54. data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
  55. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
  56. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
  57. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
  58. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
  59. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
  60. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
  61. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +172 -0
  62. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
  63. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
  64. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
  65. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
  66. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
  67. data/ruby/neo4j/driver/internal/async/network_connection.rb +196 -0
  68. data/ruby/neo4j/driver/internal/async/network_session.rb +152 -0
  69. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
  70. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
  71. data/ruby/neo4j/driver/internal/async/pool/channel.rb +63 -0
  72. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +149 -0
  73. data/ruby/neo4j/driver/internal/async/pool/controller.rb +25 -0
  74. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
  75. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
  76. data/ruby/neo4j/driver/internal/async/pool/netty_channel_tracker.rb +137 -0
  77. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
  78. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
  79. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
  80. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +214 -0
  81. data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
  82. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +58 -0
  83. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
  84. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +139 -0
  85. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +13 -0
  86. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
  87. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +159 -0
  88. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
  89. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +34 -0
  90. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +238 -0
  91. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
  92. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
  93. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +64 -0
  94. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -0
  95. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
  96. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +116 -0
  97. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +140 -0
  98. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +76 -0
  99. data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
  100. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +76 -0
  101. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +29 -0
  102. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +59 -0
  103. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +29 -0
  104. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
  105. data/ruby/neo4j/driver/internal/database_name.rb +12 -0
  106. data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
  107. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +15 -0
  108. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
  109. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
  110. data/ruby/neo4j/driver/internal/driver_factory.rb +127 -0
  111. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
  112. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +29 -0
  113. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
  114. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
  115. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
  116. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +228 -0
  117. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
  118. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
  119. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
  120. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +174 -0
  121. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +288 -0
  122. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
  123. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
  124. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +19 -0
  125. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
  126. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
  127. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +37 -0
  128. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
  129. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
  130. data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
  131. data/ruby/neo4j/driver/internal/internal_bookmark.rb +38 -0
  132. data/ruby/neo4j/driver/internal/internal_database_name.rb +11 -0
  133. data/ruby/neo4j/driver/internal/internal_driver.rb +78 -0
  134. data/ruby/neo4j/driver/internal/internal_entity.rb +22 -0
  135. data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
  136. data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
  137. data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
  138. data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
  139. data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
  140. data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
  141. data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
  142. data/ruby/neo4j/driver/internal/internal_result.rb +60 -0
  143. data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
  144. data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
  145. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
  146. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
  147. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
  148. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
  149. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
  150. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
  151. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +46 -0
  152. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
  153. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
  154. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
  155. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
  156. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
  157. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
  158. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
  159. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
  160. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
  161. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
  162. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
  163. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
  164. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
  165. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
  166. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
  167. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +18 -0
  168. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +27 -0
  169. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
  170. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
  171. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +22 -0
  172. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +26 -0
  173. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
  174. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
  175. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
  176. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
  177. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
  178. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
  179. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
  180. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
  181. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
  182. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
  183. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
  184. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
  185. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +33 -0
  186. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
  187. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +47 -0
  188. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
  189. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
  190. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
  191. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
  192. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
  193. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +79 -0
  194. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
  195. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
  196. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
  197. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
  198. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +28 -0
  199. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
  200. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
  201. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
  202. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
  203. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +34 -0
  204. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
  205. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
  206. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +26 -0
  207. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
  208. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
  209. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
  210. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
  211. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
  212. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
  213. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
  214. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
  215. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
  216. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
  217. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
  218. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
  219. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
  220. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
  221. data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
  222. data/ruby/neo4j/driver/internal/scheme.rb +32 -0
  223. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
  224. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +92 -0
  225. data/ruby/neo4j/driver/internal/security_setting.rb +73 -0
  226. data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
  227. data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
  228. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
  229. data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
  230. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
  231. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
  232. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
  233. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
  234. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
  235. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
  236. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
  237. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
  238. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
  239. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
  240. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
  241. data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
  242. data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
  243. data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
  244. data/ruby/neo4j/driver/internal/util/format.rb +39 -0
  245. data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
  246. data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
  247. data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
  248. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +109 -0
  249. data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
  250. data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
  251. data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
  252. data/ruby/neo4j/driver/logging1.rb +51 -0
  253. data/ruby/neo4j/driver/net/server_address1.rb +9 -0
  254. data/ruby/neo4j/driver/query.rb +48 -0
  255. data/ruby/neo4j/driver/records.rb +13 -0
  256. data/ruby/neo4j/driver/session_config.rb +15 -0
  257. data/ruby/neo4j/driver/transaction_config.rb +46 -0
  258. data/ruby/neo4j/driver/values.rb +26 -0
  259. data/{lib → ruby}/neo4j/driver/version.rb +1 -1
  260. data/ruby/neo4j/driver.rb +30 -0
  261. metadata +267 -92
  262. data/ffi/bolt/address.rb +0 -11
  263. data/ffi/bolt/address_resolver.rb +0 -12
  264. data/ffi/bolt/address_set.rb +0 -9
  265. data/ffi/bolt/auth.rb +0 -10
  266. data/ffi/bolt/auto_releasable.rb +0 -22
  267. data/ffi/bolt/boolean.rb +0 -9
  268. data/ffi/bolt/bytes.rb +0 -10
  269. data/ffi/bolt/config.rb +0 -45
  270. data/ffi/bolt/connection.rb +0 -44
  271. data/ffi/bolt/connector.rb +0 -17
  272. data/ffi/bolt/dictionary.rb +0 -15
  273. data/ffi/bolt/error.rb +0 -74
  274. data/ffi/bolt/float.rb +0 -9
  275. data/ffi/bolt/integer.rb +0 -9
  276. data/ffi/bolt/library.rb +0 -12
  277. data/ffi/bolt/lifecycle.rb +0 -9
  278. data/ffi/bolt/list.rb +0 -10
  279. data/ffi/bolt/log.rb +0 -16
  280. data/ffi/bolt/socket_options.rb +0 -14
  281. data/ffi/bolt/status.rb +0 -25
  282. data/ffi/bolt/string.rb +0 -9
  283. data/ffi/bolt/structure.rb +0 -10
  284. data/ffi/bolt/value.rb +0 -35
  285. data/ffi/neo4j/driver/auth_tokens.rb +0 -18
  286. data/ffi/neo4j/driver/config.rb +0 -40
  287. data/ffi/neo4j/driver/graph_database.rb +0 -52
  288. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
  289. data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
  290. data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
  291. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
  292. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
  293. data/ffi/neo4j/driver/internal/driver_factory.rb +0 -126
  294. data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
  295. data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
  296. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
  297. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
  298. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
  299. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
  300. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
  301. data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
  302. data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
  303. data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
  304. data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
  305. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
  306. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
  307. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
  308. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
  309. data/ffi/neo4j/driver/internal/network_session.rb +0 -129
  310. data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
  311. data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
  312. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
  313. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
  314. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
  315. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
  316. data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
  317. data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
  318. data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
  319. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
  320. data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
  321. data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
  322. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
  323. data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
  324. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
  325. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
  326. data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
  327. data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
  328. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
  329. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
  330. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
  331. data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
  332. data/ffi/neo4j/driver/net/server_address.rb +0 -13
  333. data/ffi/neo4j/driver/statement.rb +0 -15
  334. data/ffi/neo4j/driver/types/entity.rb +0 -21
  335. data/ffi/neo4j/driver/types/node.rb +0 -16
  336. data/ffi/neo4j/driver/types/path.rb +0 -35
  337. data/ffi/neo4j/driver/types/relationship.rb +0 -19
  338. data/ffi/neo4j/driver.rb +0 -61
  339. data/lib/neo4j/driver/internal/ruby_signature.rb +0 -18
@@ -0,0 +1,64 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class RoutingProcedureClusterCompositionProvider
5
+ PROTOCOL_ERROR_MESSAGE = "Failed to parse '%s' result received from server due to "
6
+
7
+ def initialize(clock, routing_context)
8
+ @clock = clock
9
+ @single_database_routing_procedure_runner = SingleDatabaseRoutingProcedureRunner.new(routing_context)
10
+ @multi_database_routing_procedure_runner = MultiDatabasesRoutingProcedureRunner.new(routing_context)
11
+ @route_message_routing_procedure_runner = RouteMessageRoutingProcedureRunner.new(routing_context)
12
+ end
13
+
14
+ def get_cluster_composition(connection, database_name, bookmark, impersonated_user)
15
+ runner = if Messaging::Request::MultiDatabaseUtil.supports_route_message(connection)
16
+ @route_message_routing_procedure_runner
17
+ elsif Messaging::Request::MultiDatabaseUtil.supports_multi_database(connection)
18
+ @multi_database_routing_procedure_runner
19
+ else
20
+ @single_database_routing_procedure_runner
21
+ end
22
+
23
+ runner.run(connection, database_name, bookmark, impersonated_user).then_apply do
24
+ self::process_routing_response
25
+ end
26
+ end
27
+
28
+ def process_routing_response(response)
29
+ if !response.success?
30
+ raise java.util.concurrent.CompletionException, "Failed to run '#{invoked_procedure_string(response)}' on server. Please make sure that there is a Neo4j server or cluster up running.", response.error
31
+ end
32
+
33
+ records = response.records
34
+ now = clock.millis
35
+
36
+ # the record size is wrong
37
+ if records.size != 1
38
+ raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} records received '#{records.size}' is too few or too many."
39
+ end
40
+
41
+ # failed to parse the record
42
+ begin
43
+ cluster = ClusterComposition.parse( records[0], now)
44
+ rescue Exceptions::Value::ValueException => e
45
+ raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} unparsable record received. #{e}"
46
+ end
47
+
48
+ # the cluster result is not a legal reply
49
+ if !cluster.has_routers_and_readers?
50
+ raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} no router or reader found in response."
51
+ end
52
+
53
+ # all good
54
+ cluster
55
+ end
56
+
57
+ def invoked_procedure_string(response)
58
+ query = response.procedure
59
+ query.text + '' + query.parameters
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,19 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class RoutingProcedureResponse
5
+ attr_reader :procedure, :records, :error
6
+
7
+ def initialize(procedure, records = nil, error = nil)
8
+ @procedure = procedure
9
+ @records = records
10
+ @error = error
11
+ end
12
+
13
+ def success?
14
+ !records.nil?
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class RoutingSettings
5
+ attr_reader :max_routing_failures, :retry_timeout_delay, :routing_context, :routing_table_purge_delay
6
+
7
+ def initialize(max_routing_failures, retry_timeout_delay, routing_table_purge_delay,
8
+ routing_context = RoutingContext::EMPTY)
9
+ @max_routing_failures = max_routing_failures
10
+ @retry_timeout_delay = retry_timeout_delay
11
+ @routing_context = routing_context
12
+ @routing_table_purge_delay = routing_table_purge_delay
13
+ end
14
+
15
+ STALE_ROUTING_TABLE_PURGE_DELAY = 30.seconds
16
+ DEFAULT = new(1, 5.seconds, STALE_ROUTING_TABLE_PURGE_DELAY)
17
+
18
+ def with_routing_context(new_routing_context)
19
+ self.class.new(@max_routing_failures, @retry_timeout_delay, @routing_table_purge_delay, new_routing_context)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,116 @@
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_ms)
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_ms = routing_table_purge_delay_ms
17
+ @resolved_initial_routers = []
18
+ @refresh_routing_table_future = nil
19
+ end
20
+
21
+ def on_connection_failure(address)
22
+ # remove server from the routing table, to prevent concurrent threads from making connections to this address
23
+ routing_table.forget(address)
24
+ end
25
+
26
+ def on_write_failure(address)
27
+ routing_table.forget_writer(address)
28
+ end
29
+
30
+ def ensure_routing_table(context)
31
+ # refresh is already happening concurrently, just use it's result
32
+ return @refresh_routing_table_future unless @refresh_routing_table_future.nil?
33
+
34
+ if routing_table.stale_for?(context.mode)
35
+ # existing routing table is not fresh and should be updated
36
+ @log.debug( "Routing table for database '#{@database_name.description}' is stale. #{routing_table}")
37
+
38
+ result_future = java.util.concurrent.CompletableFuture.new
39
+ @refresh_routing_table_future = result_future
40
+
41
+ @rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, nil).when_complete do |composition, completion_error|
42
+ error = Util::Futures.completion_exception_cause(completion_error)
43
+
44
+ if error.nil?
45
+ fresh_cluster_composition_fetched(composition)
46
+ else
47
+ cluster_composition_lookup_failed(error)
48
+ end
49
+ end
50
+
51
+ result_future
52
+ else
53
+ # existing routing table is fresh, use it
54
+ java.util.concurrent.CompletableFuture.completed_future(routing_table)
55
+ end
56
+ end
57
+
58
+ def update_routing_table(composition_lookup_result)
59
+ if !@refresh_routing_table_future.nil?
60
+ # refresh is already happening concurrently, just use its result
61
+ @refresh_routing_table_future
62
+ else
63
+ if composition_lookup_result.get_cluster_composition.expiration_timestamp < routing_table.expiration_timestamp
64
+ return java.util.concurrent.CompletableFuture.completed_future(routing_table)
65
+ end
66
+
67
+ result_future = java.util.concurrent.CompletableFuture.new
68
+ @refresh_routing_table_future = result_future
69
+ fresh_cluster_composition_fetched(composition_lookup_result)
70
+ result_future
71
+ end
72
+ end
73
+
74
+ private def fresh_cluster_composition_fetched(composition_lookup_result)
75
+ begin
76
+ @log.debug("Fetched cluster composition for database '#{@database_name.description}'. #{composition_lookup_result.cluster_composition}")
77
+ routing_table.update(composition_lookup_result.cluster_composition)
78
+ @routing_table_registry.remove_aged
79
+
80
+ addresses_to_retain = []
81
+ @routing_table_registry.all_servers.stream.flat_map(BoltServerAddress::unicast_stream).for_each(addresses_to_retain::add)
82
+
83
+ composition_lookup_result.resolved_initial_routers.if_present do |addresses|
84
+ @resolved_initial_routers.clear
85
+ @resolved_initial_routers << addresses
86
+ end
87
+
88
+ addresses_to_retain << @resolved_initial_routers
89
+ @connection_pool.retain_all(addresses_to_retain)
90
+
91
+ @log.debug("Updated routing table for database '#{@database_name.description}'. #{routing_table}")
92
+
93
+ routing_table_future = @refresh_routing_table_future
94
+ @refresh_routing_table_future = nil
95
+ routing_table_future.complete( routing_table)
96
+ rescue StandardError => error
97
+ cluster_composition_lookup_failed(error)
98
+ end
99
+ end
100
+
101
+ private def cluster_composition_lookup_failed(error)
102
+ @log.error("Failed to update routing table for database '#{database_name.description}'. Current routing table: #{routing_table}.", error)
103
+ @routing_table_registry.remove(database_name)
104
+ routing_table_future = @refresh_routing_table_future
105
+ @refresh_routing_table_future = nil
106
+ routing_table_future.complete_exceptionally(error)
107
+ end
108
+
109
+ # This method cannot be synchronized as it will be visited by all routing table handler's threads concurrently
110
+ def routing_table_aged?
111
+ @refresh_routing_table_future.nil? && routing_table.has_been_stale_for?(@routing_table_purge_delay_ms)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,140 @@
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_ms)
6
+ @factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
7
+ @routing_table_handlers = {}
8
+ @principal_to_database_name_stage = {}
9
+ @clock = clock
10
+ @connection_pool = connection_pool
11
+ @rediscovery = rediscovery
12
+ @log = logger
13
+ end
14
+
15
+ def ensure_routing_table(context)
16
+ ensure_database_name_is_completed(context).then_compose do |ctx_and_handler|
17
+ completed_context = ctx_and_handler.context
18
+ handler = ctx_and_handler.handler.nil? ? get_or_create(Util::Futures.join_now_or_else_throw(completed_context.database_name_future, Async::ConnectionContext::PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER)) : ctx_and_handler.handler
19
+ handler.ensure_routing_table(completed_context).then_apply(-> (_ignored) { handler })
20
+ end
21
+ end
22
+
23
+ private def ensure_database_name_is_completed(context)
24
+ context_database_name_future = context.database_name_future
25
+
26
+ if context_database_name_future.done?
27
+ context_and_handler_stage = java.util.concurrent.CompletableFuture.completed_future(ConnectionContextAndHandler.new(context, nil))
28
+ else
29
+ impersonated_user = context.impersonated_user
30
+ principal = Principal.new(impersonated_user)
31
+ database_name_stage = @principal_to_database_name_stage[principal]
32
+ handler_ref = java.util.concurrent.atomic.AtomicReference.new
33
+
34
+ if database_name_stage.nil?
35
+ database_name_future = java.util.concurrent.CompletableFuture.new
36
+ @principal_to_database_name_stage[principal] = database_name_future
37
+ database_name_stage = database_name_future
38
+
39
+ routing_table = ClusterRoutingTable.new(DatabaseNameUtil::DEFAULT_DATABASE, @clock)
40
+
41
+ @rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, impersonated_user).then_compose do |composition_lookup_result|
42
+ database_name = DatabaseNameUtil.database(composition_lookup_result.cluster_composition.database_name)
43
+ handler = get_or_create(database_name)
44
+ handler_ref.set(handler)
45
+ handler.update_routing_table(composition_lookup_result).then_apply(-> (_ignored) { database_name })
46
+ end.when_complete do |database_name, _throwable|
47
+ @principal_to_database_name_stage.delete(principal)
48
+ end.when_complete do |database_name, throwable|
49
+ if throwable.nil?
50
+ database_name_future.complete(database_name)
51
+ else
52
+ database_name_future.complete_exceptionally(throwable)
53
+ end
54
+ end
55
+ end
56
+
57
+ context_and_handler_stage =
58
+ database_name_stage.then_apply do |database_name|
59
+ context_database_name_future.complete(database_name)
60
+ ConnectionContextAndHandler.new(context, handler_ref)
61
+ end
62
+ end
63
+
64
+ context_and_handler_stage
65
+ end
66
+
67
+ def all_servers
68
+ # obviously we just had a snapshot of all servers in all routing tables
69
+ # after we read it, the set could already be changed.
70
+ servers = []
71
+
72
+ @routing_table_handlers.values.each do |table_handler|
73
+ servers << table_handler.servers
74
+ end
75
+
76
+ servers
77
+ end
78
+
79
+ def remove(database_name)
80
+ @routing_table_handlers.delete(database_name)
81
+ @log.debug("Routing table handler for database '#{database_name.description}' is removed.")
82
+ end
83
+
84
+ def remove_aged
85
+ @routing_table_handlers.each do |database_name, handler|
86
+ if handler.routing_table_aged?
87
+ @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}")
88
+ @routing_table_handlers.delete(database_name)
89
+ end
90
+ end
91
+ end
92
+
93
+ def get_routing_table_handler(database_name)
94
+ java.util.Optional.of_nullable(@routing_table_handlers[database_name])
95
+ end
96
+
97
+ def contains(database_name)
98
+ @routing_table_handlers.keys.include?(database_name)
99
+ end
100
+
101
+ def get_or_create(database_name)
102
+ @routing_table_handlers.compute_if_absent(database_name) do |name|
103
+ handler = @factory.new_instance(name, self)
104
+ @log.debug("Routing table handler for database '#{database_name.description}' is added.")
105
+ handler
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ class RoutingTableHandlerFactory
112
+ def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
113
+ @connection_pool = connection_pool
114
+ @rediscovery = rediscovery
115
+ @clock = clock
116
+ @logger = logger
117
+ @routing_table_purge_delay_ms = routing_table_purge_delay_ms
118
+ end
119
+
120
+ def new_instance(database_name, all_tables)
121
+ routing_table = ClusterRoutingTable.new(database_name, @clock)
122
+ RoutingTableHandlerImpl.new(routing_table, @rediscovery, @connection_pool, all_tables, @logger, @routing_table_purge_delay_ms)
123
+ end
124
+ end
125
+
126
+ class Principal < Struct.new(:id)
127
+ end
128
+
129
+ class ConnectionContextAndHandler
130
+ attr_reader :context, :handler
131
+
132
+ def initialize(context, handler)
133
+ @context = context
134
+ @handler = handler
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,76 @@
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
+ run_procedure(delegate, procedure, bookmark_holder).then_compose do |records|
20
+ release_connection(delegate, records).handle do |records, error|
21
+ process_procedure_response(procedure, records, error)
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def connection(connection)
29
+ Async::Connection::DirectConnection.new(connection, default_database, AccessMode::WRITE, nil)
30
+ end
31
+
32
+ def procedure_query(server_version, database_name)
33
+ if database_name.database_name.present?
34
+ 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}'"
35
+ end
36
+
37
+ Query.new(GET_ROUTING_TABLE, Values.parameters(ROUTING_CONTEXT, @context.to_map))
38
+ end
39
+
40
+ def bookmark_holder(_ignored)
41
+ BookmarkHolder::NO_OP
42
+ end
43
+
44
+ def run_procedure(connection, procedure, bookmark_holder)
45
+ connection.protocol
46
+ .run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
47
+ Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
48
+ .async_result.then_compose(Async::ResultCursor::list_async)
49
+ end
50
+
51
+ def release_connection(connection, records)
52
+ # It is not strictly required to release connection after routing procedure invocation because it'll
53
+ # be released by the PULL_ALL response handler after result is fully fetched. Such release will happen
54
+ # in background. However, releasing it early as part of whole chain makes it easier to reason about
55
+ # rediscovery in stub server tests. Some of them assume connections to instances not present in new
56
+ # routing table will be closed immediately.
57
+ connection.release.then_apply(->(_ignore) { records } )
58
+ end
59
+
60
+ def process_procedure_response(procedure, records, error)
61
+ cause = Util::Futures.completion_exception_cause(error)
62
+
63
+ return RoutingProcedureResponse.new(procedure, records) if cause.nil?
64
+
65
+ handle_error(procedure, cause)
66
+ end
67
+
68
+ def handle_error(procedure, error)
69
+ return RoutingProcedureResponse.new(procedure, records) if error.is_a? Exceptions::ClientException
70
+
71
+ raise java.util.concurrent.CompletionException, error
72
+ end
73
+ end
74
+ end
75
+ end
76
+ 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,76 @@
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
+ first_record = next_async
18
+ unless first_record
19
+ raise Exceptions::NoSuchRecordException, 'Cannot retrieve a single record, because this result is empty.'
20
+ end
21
+ if next_async
22
+ raise Exceptions::NoSuchRecordException,
23
+ 'Expected a result with a single record, but this result contains at least one more. Ensure your query returns only one record.'
24
+ end
25
+ first_record
26
+ end
27
+
28
+ def each_async(&action)
29
+ internal_for_each_async(result_future, &action)
30
+ consume_async
31
+ end
32
+
33
+ def to_async(&map_function)
34
+ @pull_all_handler.list_async(&block_given? ? map_function : :itself)
35
+ end
36
+
37
+ def discard_all_failure_async
38
+ # runError has priority over other errors and is expected to have been reported to user by now
39
+ consume_async #.chain { |_fulfilled, _summary, error| @run_error ? nil : error }
40
+ nil
41
+ end
42
+
43
+ def pull_all_failure_async
44
+ # runError has priority over other errors and is expected to have been reported to user by now
45
+ @pull_all_handler.pull_all_failure_async.then { |error| @run_error ? nil : error }
46
+ end
47
+
48
+ private def internal_for_each_async(result_future, &action)
49
+ record_future = next_async
50
+
51
+ # use async completion listener because of recursion, otherwise it is possible for
52
+ # the caller thread to get StackOverflowError when result is large and buffered
53
+ record_future.on_complete do |_fulfilled, record, error|
54
+ if error
55
+ result_future.reject(error)
56
+ elsif record
57
+ begin
58
+ yield record
59
+ rescue => action_error
60
+ result_future.reject(action_error)
61
+ return
62
+ end
63
+ internal_for_each_async(result_future, &action)
64
+ else
65
+ result_future.fulfill(nil)
66
+ end
67
+ end
68
+ end
69
+
70
+ def map_successful_run_completion_async
71
+ @run_error || self
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,29 @@
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, run_future, 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
+ @run_future = Internal::Validator.require_non_nil!(run_future)
11
+
12
+ @pull_all_handler = Internal::Validator.require_non_nil!(pull_handler)
13
+ end
14
+
15
+ def async_result
16
+ # only write and flush messages when async result is wanted.
17
+ @connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
18
+ @pull_all_handler.pre_populate_records
19
+
20
+ @run_future.handle { |_ignored, error| DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(error, @run_handler, @pull_all_handler)) }
21
+ end
22
+
23
+ def rx_result
24
+ Util::Futures.failed_future(Exceptions::ClientException.new('Driver is connected to the database that does not support driver reactive API. In order to use the driver reactive API, please upgrade to neo4j 4.0.0 or later.'))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,59 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cursor
4
+ class DisposableAsyncResultCursor
5
+ delegate :keys, :pull_all_failure_async, to: :@delegate
6
+
7
+ def initialize(delegate)
8
+ @delegate = delegate
9
+ end
10
+
11
+ def consume_async
12
+ @disposed = true
13
+ @delegate.consume_async
14
+ end
15
+
16
+ def next_async
17
+ assert_not_disposed.then_compose(-> (_ignored) { @delegate.next_async })
18
+ end
19
+
20
+ def peek_async
21
+ assert_not_disposed.then_compose(-> (_ignored) { @delegate.peek_async })
22
+ end
23
+
24
+ def single_async
25
+ assert_not_disposed.then_compose(-> (_ignored) { @delegate.single_async })
26
+ end
27
+
28
+ def for_each_async(action)
29
+ assert_not_disposed.then_compose(-> (_ignored) { @delegate.for_each_async(action) })
30
+ end
31
+
32
+ def list_async(map_function = nil)
33
+ return assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async(map_function) }) if map_function.present?
34
+
35
+ assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async })
36
+ end
37
+
38
+ def discard_all_failure_async
39
+ @disposed = true
40
+ @delegate.discard_all_failure_async
41
+ end
42
+
43
+ private def assert_not_disposed
44
+ return Util::Futures.failed_future(new_result_consumed_error) if @disposed
45
+
46
+ Util::Futures.completed_with_null
47
+ end
48
+
49
+ def disposed?
50
+ @disposed
51
+ end
52
+
53
+ def map_successful_run_completion_async
54
+ @delegate.map_successful_run_completion_async
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
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
+
22
+ def rx_result
23
+ @connection.write_and_flush(@run_message, @run_handler)
24
+ @run_future.handle { |_ignored, error| RxResultCursorImpl.new(error, @run_handler, @pull_handler) }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end