neo4j-ruby-driver 6.0.3.alpha.0 → 6.2.1.beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +113 -411
- data/{ruby → lib}/neo4j/driver/access_mode.rb +2 -1
- data/lib/neo4j/driver/auth_token_managers.rb +31 -0
- data/lib/neo4j/driver/auth_tokens.rb +41 -0
- data/lib/neo4j/driver/auto_commit_retries_mode.rb +18 -0
- data/lib/neo4j/driver/bolt/bolt_version.rb +67 -0
- data/lib/neo4j/driver/bolt/connection.rb +1091 -0
- data/lib/neo4j/driver/bolt/handshake.rb +236 -0
- data/lib/neo4j/driver/bolt/message/failure.rb +139 -0
- data/lib/neo4j/driver/bolt/message/ignored.rb +27 -0
- data/lib/neo4j/driver/bolt/message/record.rb +30 -0
- data/lib/neo4j/driver/bolt/message/success.rb +34 -0
- data/lib/neo4j/driver/bolt/message.rb +112 -0
- data/lib/neo4j/driver/bolt/pool.rb +255 -0
- data/lib/neo4j/driver/bolt/protocol/base.rb +146 -0
- data/lib/neo4j/driver/bolt/protocol/v3.rb +43 -0
- data/lib/neo4j/driver/bolt/protocol/v4.rb +24 -0
- data/lib/neo4j/driver/bolt/protocol/v43.rb +28 -0
- data/lib/neo4j/driver/bolt/protocol/v44.rb +23 -0
- data/lib/neo4j/driver/bolt/protocol/v5.rb +27 -0
- data/lib/neo4j/driver/bolt/protocol/v51.rb +24 -0
- data/lib/neo4j/driver/bolt/protocol/v52.rb +28 -0
- data/lib/neo4j/driver/bolt/protocol/v53.rb +27 -0
- data/lib/neo4j/driver/bolt/protocol/v54.rb +14 -0
- data/lib/neo4j/driver/bolt/protocol/v55.rb +17 -0
- data/lib/neo4j/driver/bolt/protocol/v56.rb +14 -0
- data/lib/neo4j/driver/bolt/protocol/v57.rb +31 -0
- data/lib/neo4j/driver/bolt/protocol/v58.rb +15 -0
- data/lib/neo4j/driver/bolt/protocol/v6.rb +43 -0
- data/lib/neo4j/driver/bolt/protocol/v61.rb +21 -0
- data/lib/neo4j/driver/bolt/protocol_version_handler.rb +39 -0
- data/lib/neo4j/driver/bolt/record_buffer.rb +143 -0
- data/lib/neo4j/driver/bolt/stream_handler.rb +53 -0
- data/lib/neo4j/driver/bolt/tls_config.rb +129 -0
- data/lib/neo4j/driver/bolt/wire.rb +321 -0
- data/lib/neo4j/driver/bookmark.rb +15 -0
- data/lib/neo4j/driver/bookmark_managers.rb +39 -0
- data/lib/neo4j/driver/client_certificate.rb +19 -0
- data/lib/neo4j/driver/client_certificate_manager.rb +37 -0
- data/lib/neo4j/driver/client_certificate_managers.rb +15 -0
- data/lib/neo4j/driver/client_certificates.rb +14 -0
- data/lib/neo4j/driver/direct/connection_provider.rb +262 -0
- data/lib/neo4j/driver/driver.rb +268 -0
- data/lib/neo4j/driver/eager_result.rb +10 -0
- data/lib/neo4j/driver/exceptions/neo4j_exception.rb +16 -7
- data/lib/neo4j/driver/exceptions/no_such_record_exception.rb +1 -1
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +0 -5
- data/lib/neo4j/driver/exceptions/security_retryable_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/transaction_terminated_exception.rb +13 -0
- data/lib/neo4j/driver/graph_database.rb +29 -0
- data/lib/neo4j/driver/internal/clock.rb +20 -0
- data/lib/neo4j/driver/internal/clock_adapter.rb +21 -0
- data/lib/neo4j/driver/internal/default_bookmark_manager.rb +54 -0
- data/lib/neo4j/driver/internal/deprecator.rb +9 -5
- data/lib/neo4j/driver/internal/driver_factory.rb +128 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +14 -39
- data/lib/neo4j/driver/internal/extras.rb +23 -0
- data/lib/neo4j/driver/internal/home_db_cache.rb +57 -0
- data/lib/neo4j/driver/internal/internal_auth_token_manager.rb +37 -0
- data/lib/neo4j/driver/internal/metrics.rb +31 -0
- data/lib/neo4j/driver/internal/security/static_auth_token_manager.rb +25 -0
- data/lib/neo4j/driver/internal/validator.rb +16 -2
- data/lib/neo4j/driver/net.rb +29 -0
- data/lib/neo4j/driver/packstream/markers.rb +49 -0
- data/lib/neo4j/driver/packstream/packer.rb +335 -0
- data/lib/neo4j/driver/packstream/structure.rb +27 -0
- data/lib/neo4j/driver/packstream/unpacker.rb +170 -0
- data/lib/neo4j/driver/record.rb +43 -0
- data/lib/neo4j/driver/result.rb +282 -0
- data/lib/neo4j/driver/routing/load_balancer.rb +706 -0
- data/lib/neo4j/driver/routing/routed_connection.rb +132 -0
- data/lib/neo4j/driver/routing/routing_table.rb +127 -0
- data/lib/neo4j/driver/routing/server_address.rb +25 -0
- data/lib/neo4j/driver/routing_control.rb +13 -0
- data/lib/neo4j/driver/session.rb +577 -0
- data/lib/neo4j/driver/summary/database_info.rb +25 -0
- data/lib/neo4j/driver/summary/gql_notification.rb +38 -0
- data/lib/neo4j/driver/summary/gql_status_object.rb +35 -0
- data/lib/neo4j/driver/summary/notification.rb +46 -0
- data/lib/neo4j/driver/summary/plan.rb +23 -0
- data/lib/neo4j/driver/summary/profile.rb +28 -0
- data/lib/neo4j/driver/summary/query.rb +19 -0
- data/lib/neo4j/driver/summary/query_type.rb +5 -1
- data/lib/neo4j/driver/summary/result_summary.rb +215 -0
- data/lib/neo4j/driver/summary/server_info.rb +33 -0
- data/lib/neo4j/driver/summary/summary_counters.rb +72 -0
- data/lib/neo4j/driver/transaction.rb +344 -0
- data/lib/neo4j/driver/types/duration.rb +76 -0
- data/lib/neo4j/driver/types/entity.rb +40 -0
- data/lib/neo4j/driver/types/local_date_time.rb +77 -8
- data/lib/neo4j/driver/types/local_time.rb +50 -7
- data/lib/neo4j/driver/types/node.rb +18 -0
- data/lib/neo4j/driver/types/offset_time.rb +78 -7
- data/lib/neo4j/driver/types/path.rb +68 -0
- data/lib/neo4j/driver/types/point.rb +38 -18
- data/lib/neo4j/driver/types/relationship.rb +32 -0
- data/lib/neo4j/driver/types/temporal_value.rb +44 -0
- data/lib/neo4j/driver/types/unbound_relationship.rb +24 -0
- data/lib/neo4j/driver/types/unresolvable_zoned_date_time.rb +38 -0
- data/lib/neo4j/driver/types/unsupported_type.rb +25 -0
- data/lib/neo4j/driver/types/uuid.rb +29 -0
- data/{ruby → lib}/neo4j/driver/version.rb +1 -1
- data/lib/neo4j/driver.rb +15 -0
- data/lib/neo4j-ruby-driver_loader.rb +34 -20
- metadata +115 -441
- data/lib/neo4j/driver/internal/bolt_server_address.rb +0 -97
- data/lib/neo4j/driver/synchronizable.rb +0 -23
- data/lib/neo4j/driver/types/time.rb +0 -45
- data/ruby/neo4j/driver/auth_tokens.rb +0 -34
- data/ruby/neo4j/driver/bookmark.rb +0 -21
- data/ruby/neo4j/driver/config.rb +0 -89
- data/ruby/neo4j/driver/graph_database.rb +0 -78
- data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +0 -51
- data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +0 -22
- data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +0 -31
- data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +0 -32
- data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +0 -83
- data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +0 -22
- data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +0 -30
- data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +0 -83
- data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +0 -27
- data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +0 -113
- data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +0 -57
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +0 -26
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +0 -19
- data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +0 -36
- data/ruby/neo4j/driver/internal/async/connection/stream.rb +0 -12
- data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +0 -16
- data/ruby/neo4j/driver/internal/async/connection_context.rb +0 -10
- data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +0 -24
- data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +0 -30
- data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +0 -77
- data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +0 -41
- data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +0 -32
- data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +0 -17
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +0 -171
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +0 -42
- data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +0 -51
- data/ruby/neo4j/driver/internal/async/internal_async_session.rb +0 -92
- data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +0 -13
- data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +0 -34
- data/ruby/neo4j/driver/internal/async/network_connection.rb +0 -194
- data/ruby/neo4j/driver/internal/async/network_session.rb +0 -150
- data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +0 -110
- data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +0 -39
- data/ruby/neo4j/driver/internal/async/pool/channel.rb +0 -66
- data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +0 -31
- data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +0 -135
- data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +0 -156
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +0 -87
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +0 -52
- data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +0 -21
- data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +0 -34
- data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +0 -15
- data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +0 -17
- data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +0 -212
- data/ruby/neo4j/driver/internal/bookmark_holder.rb +0 -9
- data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +0 -48
- data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +0 -14
- data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +0 -122
- data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +0 -10
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +0 -68
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +0 -125
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +0 -13
- data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +0 -31
- data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +0 -147
- data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +0 -43
- data/ruby/neo4j/driver/internal/cluster/routing_context.rb +0 -77
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +0 -60
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +0 -35
- data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +0 -24
- data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +0 -95
- data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +0 -121
- data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +0 -73
- data/ruby/neo4j/driver/internal/connection_settings.rb +0 -16
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +0 -55
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +0 -24
- data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +0 -61
- data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +0 -24
- data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +0 -110
- data/ruby/neo4j/driver/internal/database_name_util.rb +0 -37
- data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +0 -9
- data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +0 -11
- data/ruby/neo4j/driver/internal/direct_connection_provider.rb +0 -40
- data/ruby/neo4j/driver/internal/driver_factory.rb +0 -126
- data/ruby/neo4j/driver/internal/eager_result_value.rb +0 -5
- data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +0 -20
- data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +0 -30
- data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +0 -23
- data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +0 -65
- data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +0 -34
- data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +0 -199
- data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +0 -16
- data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +0 -29
- data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +0 -32
- data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +0 -169
- data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +0 -298
- data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +0 -20
- data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +0 -34
- data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +0 -25
- data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +0 -21
- data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +0 -79
- data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +0 -38
- data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +0 -34
- data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +0 -20
- data/ruby/neo4j/driver/internal/impersonation_util.rb +0 -22
- data/ruby/neo4j/driver/internal/internal_bookmark.rb +0 -9
- data/ruby/neo4j/driver/internal/internal_database_name.rb +0 -9
- data/ruby/neo4j/driver/internal/internal_driver.rb +0 -83
- data/ruby/neo4j/driver/internal/internal_entity.rb +0 -21
- data/ruby/neo4j/driver/internal/internal_node.rb +0 -21
- data/ruby/neo4j/driver/internal/internal_pair.rb +0 -9
- data/ruby/neo4j/driver/internal/internal_path.rb +0 -35
- data/ruby/neo4j/driver/internal/internal_point2_d.rb +0 -9
- data/ruby/neo4j/driver/internal/internal_point3_d.rb +0 -6
- data/ruby/neo4j/driver/internal/internal_record.rb +0 -27
- data/ruby/neo4j/driver/internal/internal_relationship.rb +0 -27
- data/ruby/neo4j/driver/internal/internal_result.rb +0 -49
- data/ruby/neo4j/driver/internal/internal_session.rb +0 -91
- data/ruby/neo4j/driver/internal/internal_transaction.rb +0 -48
- data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +0 -29
- data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +0 -17
- data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +0 -19
- data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +0 -23
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -32
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +0 -48
- data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +0 -51
- data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +0 -33
- data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +0 -104
- data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +0 -256
- data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +0 -16
- data/ruby/neo4j/driver/internal/messaging/encode/logoff_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/logon_message_encoder.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +0 -24
- data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +0 -22
- data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +0 -16
- data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +0 -25
- data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +0 -25
- data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +0 -20
- data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +0 -20
- data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +0 -23
- data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +0 -20
- data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +0 -30
- data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +0 -19
- data/ruby/neo4j/driver/internal/messaging/request/logoff_message.rb +0 -13
- data/ruby/neo4j/driver/internal/messaging/request/logon_message.rb +0 -13
- data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +0 -26
- data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +0 -23
- data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +0 -22
- data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +0 -32
- data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +0 -20
- data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +0 -28
- data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +0 -23
- data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +0 -49
- data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +0 -24
- data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +0 -40
- data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +0 -29
- data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +0 -33
- data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +0 -34
- data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -82
- data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +0 -27
- data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +0 -29
- data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +0 -13
- data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +0 -25
- data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +0 -13
- data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +0 -19
- data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +0 -20
- data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +0 -15
- data/ruby/neo4j/driver/internal/messaging/v5/bolt_protocol_v5.rb +0 -21
- data/ruby/neo4j/driver/internal/messaging/v5/message_format_v5.rb +0 -18
- data/ruby/neo4j/driver/internal/messaging/v5/value_unpacker_v5.rb +0 -17
- data/ruby/neo4j/driver/internal/messaging/v51/bolt_protocol_v51.rb +0 -40
- data/ruby/neo4j/driver/internal/messaging/v51/message_format_v51.rb +0 -14
- data/ruby/neo4j/driver/internal/messaging/v51/message_writer_v51.rb +0 -17
- data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +0 -34
- data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +0 -46
- data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +0 -105
- data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +0 -82
- data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +0 -18
- data/ruby/neo4j/driver/internal/metrics/listener_event.rb +0 -17
- data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +0 -24
- data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +0 -15
- data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +0 -12
- data/ruby/neo4j/driver/internal/packstream/pack_input.rb +0 -47
- data/ruby/neo4j/driver/internal/packstream/pack_output.rb +0 -39
- data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +0 -324
- data/ruby/neo4j/driver/internal/packstream/pack_type.rb +0 -17
- data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +0 -13
- data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +0 -35
- data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -150
- data/ruby/neo4j/driver/internal/revocation_strategy.rb +0 -19
- data/ruby/neo4j/driver/internal/scheme.rb +0 -32
- data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +0 -15
- data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +0 -48
- data/ruby/neo4j/driver/internal/security_setting.rb +0 -66
- data/ruby/neo4j/driver/internal/session_factory_impl.rb +0 -32
- data/ruby/neo4j/driver/internal/spi/connection.rb +0 -19
- data/ruby/neo4j/driver/internal/spi/connection_pool.rb +0 -9
- data/ruby/neo4j/driver/internal/spi/response_handler.rb +0 -23
- data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +0 -7
- data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +0 -11
- data/ruby/neo4j/driver/internal/summary/internal_notification.rb +0 -16
- data/ruby/neo4j/driver/internal/summary/internal_plan.rb +0 -41
- data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +0 -32
- data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +0 -33
- data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +0 -6
- data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -18
- data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +0 -196
- data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +0 -21
- data/ruby/neo4j/driver/internal/util/certificate_tool.rb +0 -65
- data/ruby/neo4j/driver/internal/util/clock.rb +0 -29
- data/ruby/neo4j/driver/internal/util/error_util.rb +0 -104
- data/ruby/neo4j/driver/internal/util/extract.rb +0 -123
- data/ruby/neo4j/driver/internal/util/format.rb +0 -39
- data/ruby/neo4j/driver/internal/util/futures.rb +0 -99
- data/ruby/neo4j/driver/internal/util/iterables.rb +0 -35
- data/ruby/neo4j/driver/internal/util/lock_util.rb +0 -23
- data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +0 -101
- data/ruby/neo4j/driver/internal/util/mutex.rb +0 -9
- data/ruby/neo4j/driver/internal/util/preconditions.rb +0 -16
- data/ruby/neo4j/driver/internal/util/result_holder.rb +0 -72
- data/ruby/neo4j/driver/internal/util/server_version.rb +0 -60
- data/ruby/neo4j/driver/logging1.rb +0 -51
- data/ruby/neo4j/driver/net/server_address.rb +0 -9
- data/ruby/neo4j/driver/query.rb +0 -48
- data/ruby/neo4j/driver/records.rb +0 -13
- data/ruby/neo4j/driver/transaction_config.rb +0 -50
- data/ruby/neo4j/driver/values.rb +0 -26
- data/ruby/neo4j/driver.rb +0 -30
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
# Hardened connection pool. Wraps ConnectionPool::TimedStack and
|
|
7
|
+
# layers the three guarantees production callers care about:
|
|
8
|
+
#
|
|
9
|
+
# max_connection_lifetime → connections older than this are
|
|
10
|
+
# dropped on acquire (caps server-side
|
|
11
|
+
# resource growth for long-running
|
|
12
|
+
# processes).
|
|
13
|
+
# connection_liveness_check_timeout → if a connection has been
|
|
14
|
+
# idle longer than this, RESET-probe
|
|
15
|
+
# before handing it out (catches
|
|
16
|
+
# "server reaped me, client didn't
|
|
17
|
+
# notice yet").
|
|
18
|
+
# connection_acquisition_timeout → bounded wait when the pool
|
|
19
|
+
# is at its size cap (raises
|
|
20
|
+
# ClientException, not a hang).
|
|
21
|
+
#
|
|
22
|
+
# Mirrors org.neo4j.driver.internal.async.pool.NettyChannelPool
|
|
23
|
+
# in the Java reference. The acquisition-timeout slice was already
|
|
24
|
+
# in place via TimedStack; this class adds the lifetime + liveness
|
|
25
|
+
# gates and centralises the construction across the two providers.
|
|
26
|
+
class Pool
|
|
27
|
+
DEFAULT_ACQUISITION_TIMEOUT = 60
|
|
28
|
+
|
|
29
|
+
# `connect_factory` is a callable returning a freshly-opened
|
|
30
|
+
# Bolt::Connection. Wrapped, not inherited, because TimedStack
|
|
31
|
+
# owns the threading + size-cap primitive and doesn't expose
|
|
32
|
+
# hooks for "decide whether to hand out the popped item".
|
|
33
|
+
def initialize(size:, options:, connect_factory:, clock: Internal::Clock.new)
|
|
34
|
+
@options = options
|
|
35
|
+
@clock = clock
|
|
36
|
+
# connect_factory takes the auth token a fresh connection should
|
|
37
|
+
# authenticate with. pop hands it to the create block via a
|
|
38
|
+
# thread-local: the create block runs synchronously inside
|
|
39
|
+
# @stack.pop on the *calling* thread, so a thread-local is read
|
|
40
|
+
# back by the same thread that set it and can't be clobbered by a
|
|
41
|
+
# concurrent pop on another thread (a shared ivar could — this
|
|
42
|
+
# pool is shared across sessions). Keyed by object_id so distinct
|
|
43
|
+
# pools don't collide on the same thread. This lets a session
|
|
44
|
+
# create a fresh connection with its own identity (per-session
|
|
45
|
+
# auth) or the manager's current token in a single get_token call,
|
|
46
|
+
# instead of connecting as the manager and re-authing.
|
|
47
|
+
@connect_factory = connect_factory
|
|
48
|
+
@auth_key = :"bolt_pool_next_auth_#{object_id}"
|
|
49
|
+
# Companion thread-local (same pattern as @auth_key) carrying the
|
|
50
|
+
# acquisition deadline a freshly-built connection's handshake must
|
|
51
|
+
# honour — so one budget spans the home-db guess + fallback.
|
|
52
|
+
@deadline_key = :"bolt_pool_next_deadline_#{object_id}"
|
|
53
|
+
# Metrics counters (driver.metrics / testkit GetConnectionPoolMetrics):
|
|
54
|
+
# @created = live connections this pool has built (idle + in use),
|
|
55
|
+
# @leased = currently checked out. idle = created - leased. Guarded by
|
|
56
|
+
# @metrics_lock since pop/push/discard run on many session threads.
|
|
57
|
+
# @created is bumped inside the create block (only on a successful
|
|
58
|
+
# factory call — TimedStack rolls back its own count if it raises).
|
|
59
|
+
@metrics_lock = Mutex.new
|
|
60
|
+
@created = 0
|
|
61
|
+
@leased = 0
|
|
62
|
+
@stack = ConnectionPool::TimedStack.new(size: size) do
|
|
63
|
+
@connect_factory.call(Thread.current[@auth_key], Thread.current[@deadline_key]).tap { bump(created: 1) }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# A consistent [in_use, idle] snapshot read under one lock — both
|
|
68
|
+
# counters move together on discard, so reading them separately could
|
|
69
|
+
# observe an intermediate (e.g. negative idle) state.
|
|
70
|
+
def metrics_snapshot
|
|
71
|
+
@metrics_lock.synchronize { [@leased, @created - @leased] }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Pop a connection that's young enough and confirmed alive.
|
|
75
|
+
# Loops until a usable one is found or the acquisition-timeout
|
|
76
|
+
# budget runs out — every discarded slot opens room for the
|
|
77
|
+
# factory to make a fresh one.
|
|
78
|
+
def pop(auth: nil, deadline: nil)
|
|
79
|
+
# The token a freshly-built connection should authenticate with,
|
|
80
|
+
# handed to the create block via a thread-local that lives only
|
|
81
|
+
# for this pop (see #initialize). Cleared in `ensure` so it never
|
|
82
|
+
# leaks into a later create on the same thread.
|
|
83
|
+
Thread.current[@auth_key] = auth
|
|
84
|
+
# A caller-supplied deadline lets one acquisition-timeout budget span
|
|
85
|
+
# several pops (the home-db optimistic acquire + its fallback), and
|
|
86
|
+
# bounds a freshly-built connection's handshake via the create block.
|
|
87
|
+
deadline ||= current_monotonic + acquisition_timeout
|
|
88
|
+
Thread.current[@deadline_key] = deadline
|
|
89
|
+
loop do
|
|
90
|
+
timeout = [deadline - current_monotonic, 0].max
|
|
91
|
+
conn = @stack.pop(timeout: timeout)
|
|
92
|
+
return prepare(conn) if usable?(conn)
|
|
93
|
+
|
|
94
|
+
discard_on_pop(conn)
|
|
95
|
+
# Loop with whatever budget remains. A flapping server
|
|
96
|
+
# would otherwise burn the whole pool in one acquire.
|
|
97
|
+
end
|
|
98
|
+
rescue ::Timeout::Error
|
|
99
|
+
raise Exceptions::ClientException,
|
|
100
|
+
"Unable to acquire connection from the pool within configured maximum time of #{format_acquisition_timeout}"
|
|
101
|
+
ensure
|
|
102
|
+
Thread.current[@auth_key] = nil
|
|
103
|
+
Thread.current[@deadline_key] = nil
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def push(connection)
|
|
107
|
+
return unless connection
|
|
108
|
+
|
|
109
|
+
# RESET on return to the pool, clearing any residual server-side state
|
|
110
|
+
# so the next lessee gets a clean connection. Reference drivers do this
|
|
111
|
+
# unless they advertise Optimization:MinimalResets (MRI doesn't), and
|
|
112
|
+
# testkit's scripts encode the expectation (#RESET_ON_POOL_RETURN#).
|
|
113
|
+
# It also keeps the liveness probe distinct from the return-RESET, so a
|
|
114
|
+
# silently-dead connection is actually detected on re-acquire
|
|
115
|
+
# (test_should_drop_connections_failing_liveness_check).
|
|
116
|
+
#
|
|
117
|
+
# If that RESET fails the connection is dead — discard it (closing the
|
|
118
|
+
# socket) rather than pooling a broken connection (test_fail_on_reset).
|
|
119
|
+
begin
|
|
120
|
+
connection.reset!(propagate: true)
|
|
121
|
+
rescue StandardError
|
|
122
|
+
discard(connection)
|
|
123
|
+
return
|
|
124
|
+
end
|
|
125
|
+
connection.idle_since = current_monotonic
|
|
126
|
+
@stack.push(connection)
|
|
127
|
+
bump(leased: -1) # returned to the pool, now idle
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Close a checked-out connection without putting it back.
|
|
131
|
+
# Mirrors Java's pool-discard: used when the connection is in
|
|
132
|
+
# a known-bad state (server FAILED, write-failure on a
|
|
133
|
+
# NotALeader, etc.) so we don't poison the pool. Frees the
|
|
134
|
+
# TimedStack slot so the next pop can lazily build a fresh
|
|
135
|
+
# one.
|
|
136
|
+
def discard(connection)
|
|
137
|
+
close_quietly(connection)
|
|
138
|
+
@stack.decrement_created
|
|
139
|
+
# A checked-out connection removed for good: no longer created, no
|
|
140
|
+
# longer leased.
|
|
141
|
+
bump(created: -1, leased: -1)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def shutdown(&)
|
|
145
|
+
@stack.shutdown(&)
|
|
146
|
+
# Every connection is closed now — keep the metrics truthful so a
|
|
147
|
+
# post-close snapshot reports nothing live.
|
|
148
|
+
@metrics_lock.synchronize { @created = @leased = 0 }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
# Both gates: too old OR known dead. We probe only when the
|
|
154
|
+
# connection has been idle past the liveness threshold so the
|
|
155
|
+
# hot path stays single-pop / no-extra-roundtrip.
|
|
156
|
+
def usable?(conn)
|
|
157
|
+
return false if conn.nil?
|
|
158
|
+
return false if conn.closed?
|
|
159
|
+
return false if expired?(conn)
|
|
160
|
+
# A reused connection (idle_since set when it was pushed back) may have
|
|
161
|
+
# been closed by the server while parked — a cheap non-blocking
|
|
162
|
+
# peer-close check, no round-trip, catches that so we don't hand out a
|
|
163
|
+
# dead connection (and the replacement re-resolves the address). Fresh
|
|
164
|
+
# connections (idle_since nil) skip it.
|
|
165
|
+
return false if conn.idle_since && conn.broken?
|
|
166
|
+
return false if needs_liveness_check?(conn) && !conn.alive?
|
|
167
|
+
|
|
168
|
+
true
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def prepare(conn)
|
|
172
|
+
conn.idle_since = nil
|
|
173
|
+
bump(leased: 1) # checked out of the pool
|
|
174
|
+
conn
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Move both counters under a single lock so a concurrent
|
|
178
|
+
# metrics_snapshot never sees a half-applied discard (created < leased).
|
|
179
|
+
def bump(created: 0, leased: 0)
|
|
180
|
+
@metrics_lock.synchronize do
|
|
181
|
+
@created += created
|
|
182
|
+
@leased += leased
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Replacement-on-acquire close: TimedStack already counted
|
|
187
|
+
# this connection as "created" (whether it came from the stack
|
|
188
|
+
# or the factory), so we must decrement_created to free the
|
|
189
|
+
# slot — otherwise a saturated pool that keeps producing
|
|
190
|
+
# unusable connections deadlocks: the next pop sees @created
|
|
191
|
+
# == size, has nothing on the stack, and blocks until timeout.
|
|
192
|
+
def discard_on_pop(conn)
|
|
193
|
+
close_quietly(conn)
|
|
194
|
+
@stack.decrement_created
|
|
195
|
+
# Popped but never handed out (unusable) — drop from created; it was
|
|
196
|
+
# never counted as leased.
|
|
197
|
+
bump(created: -1)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def close_quietly(conn)
|
|
201
|
+
conn&.close
|
|
202
|
+
rescue StandardError
|
|
203
|
+
# Caller already has a fresh connection coming. A failure
|
|
204
|
+
# during close is noise.
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def expired?(conn)
|
|
208
|
+
return false unless max_lifetime
|
|
209
|
+
return false unless conn.created_at
|
|
210
|
+
|
|
211
|
+
current_monotonic - conn.created_at > max_lifetime
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def needs_liveness_check?(conn)
|
|
215
|
+
return false unless liveness_check_timeout
|
|
216
|
+
return false unless conn.idle_since
|
|
217
|
+
|
|
218
|
+
current_monotonic - conn.idle_since > liveness_check_timeout
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def max_lifetime
|
|
222
|
+
@max_lifetime ||= seconds(@options[:max_connection_lifetime])
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def liveness_check_timeout
|
|
226
|
+
# Memoise the sentinel separately from the value so a configured
|
|
227
|
+
# 0 (probe-every-time) still bypasses the recompute.
|
|
228
|
+
return @liveness_check_timeout if defined?(@liveness_check_timeout)
|
|
229
|
+
|
|
230
|
+
@liveness_check_timeout = seconds(@options[:connection_liveness_check_timeout])
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def acquisition_timeout
|
|
234
|
+
@acquisition_timeout ||=
|
|
235
|
+
seconds(@options[:connection_acquisition_timeout]) || DEFAULT_ACQUISITION_TIMEOUT
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Accept Numeric seconds or ActiveSupport::Duration (which
|
|
239
|
+
# responds to #to_f). nil stays nil — callers gate on it to
|
|
240
|
+
# decide whether the feature is configured at all.
|
|
241
|
+
def seconds(value)
|
|
242
|
+
value&.to_f
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def format_acquisition_timeout
|
|
246
|
+
"#{(acquisition_timeout * 1000).to_i}ms"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def current_monotonic
|
|
250
|
+
@clock.monotonic
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Base of the per-minor protocol class hierarchy. Mirrors Java's
|
|
8
|
+
# BoltProtocolVxY family in `neo4j-bolt-connection-java` — each
|
|
9
|
+
# minor version is its own subclass and only overrides what
|
|
10
|
+
# changed at that version, instead of carrying a swarm of
|
|
11
|
+
# `version >= V5_X` checks inside one big class.
|
|
12
|
+
class Base
|
|
13
|
+
attr_reader :version, :connection
|
|
14
|
+
|
|
15
|
+
def initialize(connection, version)
|
|
16
|
+
@connection = connection
|
|
17
|
+
@version = version
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Top-level HELLO builder. The shape is fixed (one map argument);
|
|
21
|
+
# subclasses override `hello_extra` to change which keys it
|
|
22
|
+
# carries at their version. `notification_config` (the driver's
|
|
23
|
+
# NotificationsConfig, a `{minimum_severity:, disabled_categories:}`
|
|
24
|
+
# hash or nil) only lands on the wire from V52 on — older versions
|
|
25
|
+
# return an empty map from `notification_config_extra`.
|
|
26
|
+
def build_hello_message(user_agent:, auth:, routing: nil, notification_config: nil)
|
|
27
|
+
extra = hello_extra(user_agent:, auth:, routing:)
|
|
28
|
+
.merge(notification_config_extra(notification_config))
|
|
29
|
+
PackStream::Structure.new(Message::HELLO, [extra.compact])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# The HELLO map. Auth lives inside HELLO through Bolt 5.0;
|
|
33
|
+
# `routing` is the routing context (nil for a direct bolt://
|
|
34
|
+
# connection, compacted away by build_hello_message). V51
|
|
35
|
+
# overrides this to drop `**auth` once auth splits out into a
|
|
36
|
+
# separate LOGON message.
|
|
37
|
+
def hello_extra(user_agent:, auth:, routing:)
|
|
38
|
+
{ user_agent:, routing:, **auth }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Notification-filtering keys for the HELLO map. Empty until V52,
|
|
42
|
+
# the first version whose server honours them (V52 overrides this).
|
|
43
|
+
def notification_config_extra(_notification_config) = {}
|
|
44
|
+
|
|
45
|
+
# Hook for V51+ (HELLO/LOGON split): the LOGON message the connection
|
|
46
|
+
# pipelines right after HELLO. nil here — older versions carry auth in
|
|
47
|
+
# the HELLO map and send no separate LOGON.
|
|
48
|
+
def build_logon_message(_auth) = nil
|
|
49
|
+
|
|
50
|
+
# Hook for V5+: lets the protocol flip the packer's UTC
|
|
51
|
+
# datetime flag (0x49 / 0x69 vs legacy 0x46 / 0x66).
|
|
52
|
+
def configure_packer(_packer); end
|
|
53
|
+
|
|
54
|
+
# Hook for per-version unpacker customisation — re-registering
|
|
55
|
+
# handlers for messages whose shape changed at this version
|
|
56
|
+
# (V57 FAILURE) or adding handlers for new struct types
|
|
57
|
+
# (V6 VECTOR / UNSUPPORTED). Called after Connection
|
|
58
|
+
# registers the common ones, so an override here wins.
|
|
59
|
+
def customize_hydration(_unpacker); end
|
|
60
|
+
|
|
61
|
+
# PackStream V2 (Bolt 6.1+) UUID codec. UUID is a version-specific
|
|
62
|
+
# type: only Protocol::V61 packs/unpacks it — every earlier version
|
|
63
|
+
# rejects it. Packing raises a ClientException naming the type;
|
|
64
|
+
# unpacking treats the 0xE0 marker as unknown.
|
|
65
|
+
def pack_uuid(_packer, value)
|
|
66
|
+
Exceptions::ClientException.unable_to_convert(value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def unpack_uuid(unpacker)
|
|
70
|
+
unpacker.raise_unknown_marker(PackStream::Markers::UUID)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# --- Message builders -------------------------------------------
|
|
74
|
+
# The protocol handler owns the wire shape of the streaming /
|
|
75
|
+
# transaction messages, mirroring Java's BoltProtocolVxY. The
|
|
76
|
+
# defaults here are the Bolt 4.0+ forms; V3 overrides the three
|
|
77
|
+
# that changed: PULL/DISCARD carry no fields, and RUN/BEGIN have
|
|
78
|
+
# no `db` (3.0 is single-database). The `db` strip is keyed on
|
|
79
|
+
# supports_multiple_databases? so it is automatic for V3.
|
|
80
|
+
|
|
81
|
+
# `notification_config` is the SESSION's NotificationsConfig (the
|
|
82
|
+
# driver's rides on HELLO). It reaches the wire only on V5_2+, where
|
|
83
|
+
# notification_config_extra emits the keys; `.compact` there drops an
|
|
84
|
+
# unset severity while keeping an explicit `disabled_categories: []`.
|
|
85
|
+
def build_run(query, parameters, extra, notification_config: nil)
|
|
86
|
+
enforce_impersonation_support!(extra[:imp_user])
|
|
87
|
+
Message.run(query, parameters,
|
|
88
|
+
strip_db(extra).merge(notification_config_extra(notification_config).compact))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def build_begin(extra, notification_config: nil)
|
|
92
|
+
enforce_impersonation_support!(extra[:imp_user])
|
|
93
|
+
Message.begin_transaction(strip_db(extra).merge(notification_config_extra(notification_config).compact))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# 4.0+ PULL carries `{n, qid}`. V3 overrides to the
|
|
97
|
+
# parameterless PULL_ALL.
|
|
98
|
+
def build_pull(extra)
|
|
99
|
+
Message.pull(extra)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# 4.0+ DISCARD carries `{n, qid}`. V3 overrides to DISCARD_ALL.
|
|
103
|
+
def build_discard(extra)
|
|
104
|
+
Message.discard(extra)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def build_telemetry(api)
|
|
108
|
+
Message.telemetry(api)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def supports_re_auth? = false
|
|
112
|
+
def supports_multiple_databases? = false
|
|
113
|
+
def supports_notification_filtering? = false
|
|
114
|
+
# TELEMETRY (driver-API usage reporting) arrived with Bolt 5.4;
|
|
115
|
+
# V54 flips this to true.
|
|
116
|
+
def supports_telemetry? = false
|
|
117
|
+
# Impersonation (imp_user on RUN/BEGIN/ROUTE) arrived with Bolt 4.4;
|
|
118
|
+
# V44 flips this to true.
|
|
119
|
+
def supports_impersonation? = false
|
|
120
|
+
|
|
121
|
+
# Fail fast when a caller asks to impersonate over a protocol
|
|
122
|
+
# that can't carry imp_user (Bolt < 4.4) — otherwise the field
|
|
123
|
+
# is silently dropped and the query runs as the authenticated
|
|
124
|
+
# user. Matches Java, which raises ClientException here. Public
|
|
125
|
+
# so Connection#route can enforce the same rule on the discovery
|
|
126
|
+
# path (a routed session impersonating against a 4.3 cluster
|
|
127
|
+
# must fail before sending ROUTE, not silently lose imp_user).
|
|
128
|
+
def enforce_impersonation_support!(imp_user)
|
|
129
|
+
return if imp_user.nil? || supports_impersonation?
|
|
130
|
+
|
|
131
|
+
raise Exceptions::ClientException,
|
|
132
|
+
"Impersonation (impersonated_user) is not supported on Bolt #{version}; requires Bolt 4.4+"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def strip_db(extra)
|
|
138
|
+
return extra if supports_multiple_databases?
|
|
139
|
+
|
|
140
|
+
extra.reject { |key, _| key.to_sym == :db }
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 3.0 protocol handler — the oldest version the driver
|
|
8
|
+
# speaks (matches the Java driver's matrix, which starts at 3.0).
|
|
9
|
+
#
|
|
10
|
+
# Differences from V4 that this class encodes:
|
|
11
|
+
# * Routing is the `dbms.cluster.routing.getRoutingTable`
|
|
12
|
+
# procedure (RUN), not a server ROUTE message — but the HELLO
|
|
13
|
+
# still carries the routing context, matching the Java driver
|
|
14
|
+
# (and so JRuby): testkit gates `routing` in the 3.0 HELLO on
|
|
15
|
+
# driver name java/ruby specifically.
|
|
16
|
+
# * Single-database: no `db` field on RUN / BEGIN. Inherits
|
|
17
|
+
# supports_multiple_databases? = false from Base, so the
|
|
18
|
+
# strip_db in build_run / build_begin happens automatically.
|
|
19
|
+
# * Streaming is all-or-nothing: PULL_ALL (0x3F) and
|
|
20
|
+
# DISCARD_ALL (0x2F) take no fields, unlike the 4.0+
|
|
21
|
+
# PULL / DISCARD which carry `{n, qid}`.
|
|
22
|
+
class V3 < Base
|
|
23
|
+
# HELLO is the inherited auth-in-HELLO form. On 3.0, `routing`
|
|
24
|
+
# is the context for a neo4j:// driver and nil for bolt://
|
|
25
|
+
# (compacted away), so a direct 3.0 connection sends no routing
|
|
26
|
+
# key — matching the Java driver, which testkit gates on driver
|
|
27
|
+
# name for the 3.0 HELLO.
|
|
28
|
+
|
|
29
|
+
# PULL_ALL: no metadata map. The caller still passes `{n:}` for
|
|
30
|
+
# the 4.0+ path; on 3.0 we discard it and send the bare struct.
|
|
31
|
+
def build_pull(_extra)
|
|
32
|
+
PackStream::Structure.new(Message::PULL, [])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# DISCARD_ALL: no metadata map.
|
|
36
|
+
def build_discard(_extra)
|
|
37
|
+
PackStream::Structure.new(Message::DISCARD, [])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 4.x handler for the pre-4.4 wire form. The driver
|
|
8
|
+
# negotiates it for 4.2 and 4.3 (see ProtocolVersionHandler);
|
|
9
|
+
# 4.4's wire additions (imp_user, the ROUTE map form) live in
|
|
10
|
+
# the V44 subclass, which every 5.x handler descends from.
|
|
11
|
+
class V4 < Base
|
|
12
|
+
def supports_multiple_databases? = true
|
|
13
|
+
|
|
14
|
+
# ROUTE's third field is the target database as a bare string
|
|
15
|
+
# (or null for the home db). 4.4 changed it to a `{db, imp_user}`
|
|
16
|
+
# map — V44 overrides this; imp_user is unused here.
|
|
17
|
+
def build_route(routing_context, bookmarks, database, _imp_user)
|
|
18
|
+
Message.route(routing_context, bookmarks, database)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 4.3. First version to offer the "utc" datetime patch
|
|
8
|
+
# (HELLO `patch_bolt: ["utc"]`, opting into UTC-seconds encoding
|
|
9
|
+
# 0x49/0x69). Otherwise identical to V4 — 4.2 does not support the
|
|
10
|
+
# patch. V44 and every 5.x descend from here and inherit the
|
|
11
|
+
# capability; V5 turns it back off since 5.0+ makes UTC native. The
|
|
12
|
+
# packer only switches once the server confirms the patch in the
|
|
13
|
+
# HELLO SUCCESS (Connection#perform_hello).
|
|
14
|
+
class V43 < V4
|
|
15
|
+
# Advertise the "utc" patch in HELLO. Inherited by V44 (and thus the
|
|
16
|
+
# 5.x ladder); V5 resets patch_bolt_extra to {} since 5.0+ makes UTC
|
|
17
|
+
# native. The packer only switches once the server confirms the patch
|
|
18
|
+
# in the HELLO SUCCESS (Connection#perform_hello).
|
|
19
|
+
def hello_extra(user_agent:, auth:, routing:)
|
|
20
|
+
super.merge(patch_bolt_extra)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def patch_bolt_extra = { patch_bolt: ['utc'] }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 4.4. Adds impersonation (imp_user on RUN/BEGIN/ROUTE) and
|
|
8
|
+
# changes ROUTE's third field from a bare database string to a
|
|
9
|
+
# `{db, imp_user}` map. Descends from V43 so it inherits the "utc"
|
|
10
|
+
# patch capability; every 5.x handler descends from this class, so
|
|
11
|
+
# they inherit impersonation, the ROUTE map form, and (until V5
|
|
12
|
+
# turns it off) the patch.
|
|
13
|
+
class V44 < V43
|
|
14
|
+
def supports_impersonation? = true
|
|
15
|
+
|
|
16
|
+
def build_route(routing_context, bookmarks, database, imp_user)
|
|
17
|
+
Message.route(routing_context, bookmarks, { db: database, imp_user: }.compact)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.0. HELLO shape is unchanged from V44 (auth still lives
|
|
8
|
+
# inside HELLO; 5.1 is where it splits out). The visible delta is
|
|
9
|
+
# on the wire: 5.0+ mandates UTC-seconds datetime encoding
|
|
10
|
+
# (structures 0x49 / 0x69) for both pack and hydrate. The 0x46 /
|
|
11
|
+
# 0x66 hydration handlers stay registered for back-compat reads
|
|
12
|
+
# from older sources. Extends V44 so it keeps impersonation and
|
|
13
|
+
# the ROUTE map form.
|
|
14
|
+
class V5 < V44
|
|
15
|
+
def configure_packer(packer)
|
|
16
|
+
packer.use_utc_datetime = true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# 5.0+ makes UTC-seconds datetimes native, so drop the "utc" HELLO
|
|
20
|
+
# patch V43 added — V43#hello_extra (inherited via V44) merges this
|
|
21
|
+
# empty map, so 5.0 sends no patch_bolt.
|
|
22
|
+
def patch_bolt_extra = {}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.1. HELLO no longer carries auth — a separate LOGON
|
|
8
|
+
# (signature 0x6A) follows immediately. This also unlocks
|
|
9
|
+
# re-authentication on a live connection (`LOGOFF` + `LOGON`),
|
|
10
|
+
# which the public driver doesn't expose yet but the protocol
|
|
11
|
+
# supports from here on.
|
|
12
|
+
class V51 < V5
|
|
13
|
+
def hello_extra(user_agent:, auth:, routing:)
|
|
14
|
+
{ user_agent:, routing: }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def build_logon_message(auth) = Message.logon(auth)
|
|
18
|
+
|
|
19
|
+
def supports_re_auth? = true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.2. Server now honours notification-filtering fields in
|
|
8
|
+
# HELLO (`notifications_minimum_severity`,
|
|
9
|
+
# `notifications_disabled_categories`). The driver's
|
|
10
|
+
# NotificationsConfig (a `{minimum_severity:, disabled_categories:}`
|
|
11
|
+
# hash, or nil) is mapped straight onto those keys here; the outer
|
|
12
|
+
# `build_hello_message.compact` drops an unset severity while keeping
|
|
13
|
+
# an explicit empty `disabled_categories: []` (which the server reads
|
|
14
|
+
# as "re-enable every category").
|
|
15
|
+
class V52 < V51
|
|
16
|
+
def supports_notification_filtering? = true
|
|
17
|
+
|
|
18
|
+
def notification_config_extra(config)
|
|
19
|
+
return {} unless config
|
|
20
|
+
|
|
21
|
+
{ notifications_minimum_severity: config[:minimum_severity],
|
|
22
|
+
notifications_disabled_categories: config[:disabled_categories] }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.3. HELLO grows a required `bolt_agent` map identifying
|
|
8
|
+
# the driver (product is required; the rest is informational).
|
|
9
|
+
class V53 < V52
|
|
10
|
+
def hello_extra(user_agent:, auth:, routing:)
|
|
11
|
+
super.merge(bolt_agent: bolt_agent)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def bolt_agent
|
|
17
|
+
{
|
|
18
|
+
product: "neo4j-ruby-driver/#{Neo4j::Driver::VERSION}",
|
|
19
|
+
language: "Ruby/#{RUBY_VERSION}",
|
|
20
|
+
platform: RUBY_PLATFORM
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.5. Server stops emitting the legacy `notifications`
|
|
8
|
+
# list in SUCCESS metadata and switches to GQL status objects
|
|
9
|
+
# (`statuses`). Hydration-side: ResultSummary#notifications
|
|
10
|
+
# already falls back to `statuses` when the legacy key is
|
|
11
|
+
# absent, so there's nothing version-specific to override here.
|
|
12
|
+
class V55 < V54
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Neo4j
|
|
4
|
+
module Driver
|
|
5
|
+
module Bolt
|
|
6
|
+
module Protocol
|
|
7
|
+
# Bolt 5.6. No client-visible wire change vs 5.5 — server-side
|
|
8
|
+
# capability bump only (vector type availability on the server).
|
|
9
|
+
class V56 < V55
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|