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.
- checksums.yaml +4 -4
- data/README.md +37 -42
- data/lib/loader.rb +5 -3
- data/lib/neo4j/driver/auto_closable.rb +2 -2
- data/lib/neo4j/driver/exceptions/authentication_exception.rb +6 -1
- data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
- data/lib/neo4j/driver/{types/bytes.rb → exceptions/certificate_exception.rb} +2 -2
- data/lib/neo4j/driver/exceptions/client_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/database_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
- data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +7 -0
- data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/security_exception.rb +5 -1
- data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +2 -0
- data/lib/neo4j/driver/exceptions/session_expired_exception.rb +4 -0
- data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
- data/lib/neo4j/driver/exceptions/transient_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +1 -0
- data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
- data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
- data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
- data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +1 -1
- data/lib/neo4j/driver/internal/validator.rb +5 -4
- data/{ffi/neo4j/driver/summary/statement_type.rb → lib/neo4j/driver/summary/query_type.rb} +1 -3
- data/lib/neo4j/driver/synchronizable.rb +23 -0
- data/lib/neo4j/driver/types/time.rb +4 -2
- data/lib/neo4j_ruby_driver.rb +5 -10
- data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
- data/ruby/neo4j/driver/auth_tokens.rb +34 -0
- data/ruby/neo4j/driver/bookmark.rb +21 -0
- data/ruby/neo4j/driver/config.rb +89 -0
- data/ruby/neo4j/driver/graph_database.rb +80 -0
- data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
- data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +83 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
- data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
- data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
- data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
- data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
- data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
- data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
- data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
- data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
- data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
- data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
- data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
- data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
- data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
- data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +171 -0
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
- data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
- data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
- data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
- data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
- data/ruby/neo4j/driver/internal/async/network_connection.rb +194 -0
- data/ruby/neo4j/driver/internal/async/network_session.rb +150 -0
- data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
- data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
- data/ruby/neo4j/driver/internal/async/pool/channel.rb +62 -0
- data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +31 -0
- data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +135 -0
- data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +156 -0
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
- data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
- data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
- data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +15 -0
- data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
- data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +212 -0
- data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +48 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +122 -0
- data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +10 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +125 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
- data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +31 -0
- data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +147 -0
- data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
- data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +60 -0
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +35 -0
- data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
- data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +95 -0
- data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +121 -0
- data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +73 -0
- data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +55 -0
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +24 -0
- data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +61 -0
- data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +24 -0
- data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
- data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
- data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +9 -0
- data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
- data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
- data/ruby/neo4j/driver/internal/driver_factory.rb +126 -0
- data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
- data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +30 -0
- data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
- data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
- data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +199 -0
- data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
- data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
- data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +168 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +298 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
- data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +25 -0
- data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
- data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
- data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +38 -0
- data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
- data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
- data/ruby/neo4j/driver/internal/internal_bookmark.rb +36 -0
- data/ruby/neo4j/driver/internal/internal_database_name.rb +9 -0
- data/ruby/neo4j/driver/internal/internal_driver.rb +74 -0
- data/ruby/neo4j/driver/internal/internal_entity.rb +20 -0
- data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
- data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
- data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
- data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
- data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
- data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
- data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
- data/ruby/neo4j/driver/internal/internal_result.rb +49 -0
- data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
- data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
- data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
- data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
- data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
- data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +48 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
- data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
- data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +24 -0
- data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +22 -0
- data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
- data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +25 -0
- data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +25 -0
- data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
- data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
- data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
- data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
- data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
- data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
- data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +28 -0
- data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +49 -0
- data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
- data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
- data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
- data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
- data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
- data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +82 -0
- data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
- data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
- data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
- data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
- data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
- data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
- data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
- data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +15 -0
- data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
- data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
- data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
- data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
- data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
- data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
- data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
- data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
- data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
- data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
- data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
- data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
- data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
- data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
- data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
- data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
- data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
- data/ruby/neo4j/driver/internal/scheme.rb +32 -0
- data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
- data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +48 -0
- data/ruby/neo4j/driver/internal/security_setting.rb +66 -0
- data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
- data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
- data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
- data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
- data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
- data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
- data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
- data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
- data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
- data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
- data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
- data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
- data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
- data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
- data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
- data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
- data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
- data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
- data/ruby/neo4j/driver/internal/util/format.rb +39 -0
- data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
- data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
- data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
- data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +107 -0
- data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
- data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
- data/ruby/neo4j/driver/internal/util/result_holder.rb +72 -0
- data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
- data/ruby/neo4j/driver/logging1.rb +51 -0
- data/ruby/neo4j/driver/net/server_address.rb +9 -0
- data/ruby/neo4j/driver/query.rb +48 -0
- data/ruby/neo4j/driver/records.rb +13 -0
- data/ruby/neo4j/driver/transaction_config.rb +50 -0
- data/ruby/neo4j/driver/values.rb +26 -0
- data/{lib → ruby}/neo4j/driver/version.rb +1 -1
- data/ruby/neo4j/driver.rb +29 -0
- metadata +264 -101
- data/ffi/bolt/address.rb +0 -11
- data/ffi/bolt/address_resolver.rb +0 -12
- data/ffi/bolt/address_set.rb +0 -9
- data/ffi/bolt/auth.rb +0 -10
- data/ffi/bolt/auto_releasable.rb +0 -22
- data/ffi/bolt/boolean.rb +0 -9
- data/ffi/bolt/bytes.rb +0 -10
- data/ffi/bolt/config.rb +0 -45
- data/ffi/bolt/connection.rb +0 -44
- data/ffi/bolt/connector.rb +0 -17
- data/ffi/bolt/dictionary.rb +0 -15
- data/ffi/bolt/error.rb +0 -74
- data/ffi/bolt/float.rb +0 -9
- data/ffi/bolt/integer.rb +0 -9
- data/ffi/bolt/library.rb +0 -12
- data/ffi/bolt/lifecycle.rb +0 -9
- data/ffi/bolt/list.rb +0 -10
- data/ffi/bolt/log.rb +0 -16
- data/ffi/bolt/socket_options.rb +0 -14
- data/ffi/bolt/status.rb +0 -25
- data/ffi/bolt/string.rb +0 -9
- data/ffi/bolt/structure.rb +0 -10
- data/ffi/bolt/value.rb +0 -35
- data/ffi/neo4j/driver/auth_tokens.rb +0 -18
- data/ffi/neo4j/driver/config.rb +0 -40
- data/ffi/neo4j/driver/graph_database.rb +0 -52
- data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
- data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
- data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
- data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
- data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
- data/ffi/neo4j/driver/internal/driver_factory.rb +0 -125
- data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
- data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
- data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
- data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
- data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
- data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
- data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
- data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
- data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
- data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
- data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
- data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
- data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
- data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
- data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
- data/ffi/neo4j/driver/internal/network_session.rb +0 -129
- data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
- data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
- data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
- data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
- data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
- data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
- data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
- data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
- data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
- data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
- data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
- data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
- data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
- data/ffi/neo4j/driver/net/server_address.rb +0 -13
- data/ffi/neo4j/driver/statement.rb +0 -15
- data/ffi/neo4j/driver/types/entity.rb +0 -21
- data/ffi/neo4j/driver/types/node.rb +0 -16
- data/ffi/neo4j/driver/types/path.rb +0 -35
- data/ffi/neo4j/driver/types/relationship.rb +0 -19
- data/ffi/neo4j/driver.rb +0 -61
- 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,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
|