pg_eventstore 1.13.4 → 3.0.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/.rubocop.yml +11 -2
- data/CHANGELOG.md +195 -16
- data/README.md +33 -10
- data/db/migrations/10_setup_pg_cron.rb +1 -0
- data/db/migrations/11_add_events_link_global_position.sql +1 -0
- data/db/migrations/12_migrate_legacy_links.rb +83 -0
- data/db/migrations/13_remove_events_link_id.sql +6 -0
- data/db/migrations/14_remove_ids_events_id_index.sql +1 -0
- data/db/migrations/15_create_streams_global_index.sql +17 -0
- data/db/migrations/16_populate_streams_global_index.rb +150 -0
- data/db/migrations/17_create_events_global_index.sql +62 -0
- data/db/migrations/18_populate_events_global_index.rb +124 -0
- data/db/migrations/19_populate_events_global_index_p2.rb +25 -0
- data/db/migrations/20_migrate_subscriptions_current_position.sql +19 -0
- data/db/migrations/21_create_partitions_stats.sql +2 -0
- data/db/migrations/22_drop_streams_sql_view.sql +2 -0
- data/db/migrations/23_adjust_partitions_indexes.sql +5 -0
- data/db/migrations/24_drop_legacy_events_indexes.sql +3 -0
- data/db/migrations/25_add_parent_partitions_info_to_partitions.sql +16 -0
- data/db/migrations/26_change_events_stream_revision_type.rb +35 -0
- data/db/migrations/27_drop_events_horizon.sql +3 -0
- data/db/migrations/28_create_maintenance_tasks.sql +8 -0
- data/db/migrations/29_create_event_markers.sql +35 -0
- data/db/migrations/30_improve_partitions_search_in_admin_ui.rb +24 -0
- data/db/migrations/31_drop_events_id_default_value.sql +1 -0
- data/db/migrations/32_create_parittions_triggers.sql +101 -0
- data/db/migrations/9_create_events_horizon.sql +21 -0
- data/docs/AGENTS.fragment.md +696 -0
- data/docs/admin_ui.md +3 -1
- data/docs/appending_events.md +110 -49
- data/docs/configuration.md +69 -36
- data/docs/event_tracing.md +55 -0
- data/docs/events_and_streams.md +54 -30
- data/docs/how_it_works.md +57 -16
- data/docs/linking_events.md +2 -1
- data/docs/maintenance.md +14 -5
- data/docs/multiple_commands.md +30 -6
- data/docs/reading_events.md +208 -43
- data/docs/reading_streams.md +50 -0
- data/docs/replication.md +99 -0
- data/docs/subscriptions.md +165 -35
- data/docs/writing_middleware.md +25 -8
- data/ext/pg_eventstore_ext/extconf.rb +5 -0
- data/ext/pg_eventstore_ext/pg_eventstore_ext.c +74 -0
- data/lib/pg_eventstore/async_runner.rb +63 -0
- data/lib/pg_eventstore/basic_config.rb +15 -0
- data/lib/pg_eventstore/callbacks.rb +7 -5
- data/lib/pg_eventstore/chunks/chunk.rb +31 -0
- data/lib/pg_eventstore/chunks/read_api_events_index_chunk.rb +83 -0
- data/lib/pg_eventstore/chunks/replica_events_index_chunk.rb +35 -0
- data/lib/pg_eventstore/chunks/repository.rb +73 -0
- data/lib/pg_eventstore/chunks/subscription_checkpoint_chunk.rb +48 -0
- data/lib/pg_eventstore/chunks/subscription_events_index_chunk.rb +99 -0
- data/lib/pg_eventstore/chunks.rb +14 -0
- data/lib/pg_eventstore/cli/try_to_delete_subscriptions_set.rb +2 -2
- data/lib/pg_eventstore/client.rb +167 -52
- data/lib/pg_eventstore/commands/append.rb +62 -43
- data/lib/pg_eventstore/commands/delete_event.rb +7 -8
- data/lib/pg_eventstore/commands/delete_stream.rb +3 -3
- data/lib/pg_eventstore/commands/event_modifiers/prepare_link_event.rb +11 -6
- data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
- data/lib/pg_eventstore/commands/link_to.rb +9 -9
- data/lib/pg_eventstore/commands/multiple.rb +2 -2
- data/lib/pg_eventstore/commands/read.rb +23 -5
- data/lib/pg_eventstore/commands/read_grouped.rb +46 -0
- data/lib/pg_eventstore/commands/read_streams.rb +18 -0
- data/lib/pg_eventstore/commands/read_streams_paginated.rb +56 -0
- data/lib/pg_eventstore/commands/regular_stream_read_paginated.rb +4 -4
- data/lib/pg_eventstore/commands/revision_check/current_revision.rb +51 -0
- data/lib/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rb +46 -0
- data/lib/pg_eventstore/commands/revision_check/expected_revision.rb +135 -0
- data/lib/pg_eventstore/commands/revision_check/stream_revision_check.rb +98 -0
- data/lib/pg_eventstore/commands/revision_check/stream_revision_comparison.rb +36 -0
- data/lib/pg_eventstore/commands/stream_revision.rb +14 -0
- data/lib/pg_eventstore/commands/system_stream_read_paginated.rb +4 -4
- data/lib/pg_eventstore/commands.rb +4 -2
- data/lib/pg_eventstore/config.rb +30 -9
- data/lib/pg_eventstore/connection.rb +22 -37
- data/lib/pg_eventstore/errors.rb +137 -11
- data/lib/pg_eventstore/event.rb +39 -7
- data/lib/pg_eventstore/event_deserializer.rb +5 -4
- data/lib/pg_eventstore/event_global_index.rb +118 -0
- data/lib/pg_eventstore/event_marker.rb +16 -0
- data/lib/pg_eventstore/event_marker_index.rb +25 -0
- data/lib/pg_eventstore/event_serializer.rb +6 -0
- data/lib/pg_eventstore/extensions/acts_as_configurable.rb +88 -0
- data/lib/pg_eventstore/extensions/options_defaults.rb +25 -0
- data/lib/pg_eventstore/extensions/options_extension.rb +42 -13
- data/lib/pg_eventstore/feature_marker.rb +18 -0
- data/lib/pg_eventstore/maintenance.rb +11 -6
- data/lib/pg_eventstore/middleware/event_tracing.rb +53 -0
- data/lib/pg_eventstore/partition.rb +6 -0
- data/lib/pg_eventstore/pg_connection.rb +70 -14
- data/lib/pg_eventstore/queries/event_marker_queries.rb +74 -0
- data/lib/pg_eventstore/queries/event_queries.rb +9 -95
- data/lib/pg_eventstore/queries/events_global_index_queries.rb +131 -0
- data/lib/pg_eventstore/queries/index_filtering_queries.rb +179 -0
- data/lib/pg_eventstore/queries/links_resolver.rb +10 -7
- data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
- data/lib/pg_eventstore/queries/partition_queries.rb +46 -104
- data/lib/pg_eventstore/queries/replica_queries.rb +110 -0
- data/lib/pg_eventstore/queries/streams_global_index_queries.rb +163 -0
- data/lib/pg_eventstore/queries/transaction_queries.rb +58 -10
- data/lib/pg_eventstore/queries.rb +29 -1
- data/lib/pg_eventstore/query_builders/basic_filtering.rb +38 -5
- data/lib/pg_eventstore/query_builders/event_markers_filtering.rb +47 -0
- data/lib/pg_eventstore/query_builders/event_markers_index_filtering.rb +275 -0
- data/lib/pg_eventstore/query_builders/event_subscription_positions_filtering.rb +37 -0
- data/lib/pg_eventstore/query_builders/events_filtering.rb +15 -164
- data/lib/pg_eventstore/query_builders/events_global_index_filtering.rb +227 -0
- data/lib/pg_eventstore/query_builders/filters/collection.rb +324 -0
- data/lib/pg_eventstore/query_builders/filters/event_type_filter.rb +37 -0
- data/lib/pg_eventstore/query_builders/filters/filter_row.rb +54 -0
- data/lib/pg_eventstore/query_builders/filters/marker_filter.rb +20 -0
- data/lib/pg_eventstore/query_builders/filters/marker_filter_row.rb +49 -0
- data/lib/pg_eventstore/query_builders/filters/stream_filter.rb +48 -0
- data/lib/pg_eventstore/query_builders/index_based_events_filtering.rb +260 -0
- data/lib/pg_eventstore/query_builders/partitions_filtering.rb +175 -51
- data/lib/pg_eventstore/query_builders/read_cursor/stream_cursor.rb +122 -0
- data/lib/pg_eventstore/query_builders/streams_global_index_filtering.rb +83 -0
- data/lib/pg_eventstore/query_builders/subscription_events_filtering.rb +79 -0
- data/lib/pg_eventstore/query_strategy/async.rb +64 -0
- data/lib/pg_eventstore/query_strategy/foreground.rb +25 -0
- data/lib/pg_eventstore/query_strategy.rb +19 -0
- data/lib/pg_eventstore/raw_event.rb +46 -0
- data/lib/pg_eventstore/rspec/test_helpers.rb +21 -8
- data/lib/pg_eventstore/sql_builder.rb +87 -8
- data/lib/pg_eventstore/stream.rb +14 -17
- data/lib/pg_eventstore/stream_global_index.rb +28 -0
- data/lib/pg_eventstore/subscriptions/basic_runner.rb +4 -4
- data/lib/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rb +5 -17
- data/lib/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rb +36 -0
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rb +13 -1
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +19 -14
- data/lib/pg_eventstore/subscriptions/events_processor.rb +21 -19
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/multiple.rb +63 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/replica.rb +68 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/single.rb +62 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer.rb +44 -0
- data/lib/pg_eventstore/subscriptions/events_subscription_position_worker.rb +68 -0
- data/lib/pg_eventstore/subscriptions/queries/event_subscription_position_queries.rb +177 -0
- data/lib/pg_eventstore/subscriptions/queries/subscription_command_queries.rb +5 -5
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +80 -56
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rb +2 -2
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rb +1 -1
- data/lib/pg_eventstore/subscriptions/replica_subscription_handler.rb +140 -0
- data/lib/pg_eventstore/subscriptions/replica_subscription_runner.rb +9 -0
- data/lib/pg_eventstore/subscriptions/subscription.rb +9 -7
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/collection.rb +36 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/index_read_strategy.rb +82 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/replication_strategy.rb +75 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategy.rb +31 -0
- data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +26 -2
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +5 -5
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -22
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
- data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +10 -11
- data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +84 -29
- data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
- data/lib/pg_eventstore/tasks/setup.rake +32 -33
- data/lib/pg_eventstore/utils.rb +39 -0
- data/lib/pg_eventstore/version.rb +1 -1
- data/lib/pg_eventstore/web/application.rb +104 -20
- data/lib/pg_eventstore/web/paginator/base_collection.rb +5 -1
- data/lib/pg_eventstore/web/paginator/event_types_collection.rb +14 -4
- data/lib/pg_eventstore/web/paginator/events_collection.rb +29 -33
- data/lib/pg_eventstore/web/paginator/helpers.rb +19 -12
- data/lib/pg_eventstore/web/paginator/markers_collection.rb +48 -0
- data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +13 -2
- data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +21 -11
- data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +18 -4
- data/lib/pg_eventstore/web/paginator/streams_collection.rb +95 -0
- data/lib/pg_eventstore/web/public/javascripts/pg_eventstore.js +49 -22
- data/lib/pg_eventstore/web/subscriptions/helpers.rb +2 -2
- data/lib/pg_eventstore/web/subscriptions/set_collection.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/with_state/set_collection.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/with_state/subscriptions.rb +1 -1
- data/lib/pg_eventstore/web/views/home/dashboard.erb +11 -9
- data/lib/pg_eventstore/web/views/home/partials/event_filter.erb +18 -5
- data/lib/pg_eventstore/web/views/home/partials/events.erb +38 -1
- data/lib/pg_eventstore/web/views/home/partials/markers_filter.erb +18 -0
- data/lib/pg_eventstore/web/views/layouts/application.erb +6 -0
- data/lib/pg_eventstore/web/views/streams/index.erb +110 -0
- data/lib/pg_eventstore/web/views/streams/partials/streams.erb +11 -0
- data/lib/pg_eventstore/web/views/subscriptions/index.erb +4 -1
- data/lib/pg_eventstore/web.rb +2 -0
- data/lib/pg_eventstore.rb +26 -63
- data/pg_eventstore.gemspec +6 -4
- data/sig/interfaces/_raw_events_handler.rbs +3 -0
- data/sig/interfaces/subscription_handler.rbs +1 -1
- data/sig/pg/result.rbs +9 -0
- data/sig/pg_eventstore/async_runner.rbs +13 -0
- data/sig/pg_eventstore/basic_config.rbs +9 -0
- data/sig/pg_eventstore/chunks/chunk.rbs +13 -0
- data/sig/pg_eventstore/chunks/read_api_events_index_chunk.rbs +30 -0
- data/sig/pg_eventstore/chunks/replica_events_index_chunk.rbs +11 -0
- data/sig/pg_eventstore/chunks/repository.rbs +22 -0
- data/sig/pg_eventstore/chunks/subscription_checkpoint_chunk.rbs +18 -0
- data/sig/pg_eventstore/chunks/subscription_events_index_chunk.rbs +37 -0
- data/sig/pg_eventstore/client.rbs +41 -43
- data/sig/pg_eventstore/commands/append.rbs +11 -25
- data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +9 -12
- data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +5 -4
- data/sig/pg_eventstore/commands/link_to.rbs +6 -11
- data/sig/pg_eventstore/commands/multiple.rbs +1 -1
- data/sig/pg_eventstore/commands/read.rbs +2 -5
- data/sig/pg_eventstore/commands/read_grouped.rbs +7 -0
- data/sig/pg_eventstore/commands/read_streams.rbs +7 -0
- data/sig/pg_eventstore/commands/read_streams_paginated.rbs +16 -0
- data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +9 -17
- data/sig/pg_eventstore/commands/revision_check/current_revision.rbs +25 -0
- data/sig/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rbs +14 -0
- data/sig/pg_eventstore/commands/revision_check/expected_revision.rbs +67 -0
- data/sig/pg_eventstore/commands/revision_check/stream_revision_check.rbs +20 -0
- data/sig/pg_eventstore/commands/revision_check/stream_revision_comparison.rbs +9 -0
- data/sig/pg_eventstore/commands/stream_revision.rbs +7 -0
- data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +9 -14
- data/sig/pg_eventstore/config.rbs +15 -6
- data/sig/pg_eventstore/connection.rbs +11 -18
- data/sig/pg_eventstore/errors.rbs +64 -34
- data/sig/pg_eventstore/event.rbs +20 -6
- data/sig/pg_eventstore/event_deserializer.rbs +5 -10
- data/sig/pg_eventstore/event_global_index.rbs +60 -0
- data/sig/pg_eventstore/event_marker.rbs +9 -0
- data/sig/pg_eventstore/event_marker_index.rbs +12 -0
- data/sig/pg_eventstore/extensions/acts_as_configurable.rbs +29 -0
- data/sig/pg_eventstore/extensions/options_defaults.rbs +7 -0
- data/sig/pg_eventstore/extensions/options_extension.rbs +9 -1
- data/sig/pg_eventstore/feature_marker.rbs +10 -0
- data/sig/pg_eventstore/maintenance.rbs +12 -8
- data/sig/pg_eventstore/middleware/event_trace.rbs +14 -0
- data/sig/pg_eventstore/partition.rbs +2 -4
- data/sig/pg_eventstore/pg_connection.rbs +8 -0
- data/sig/pg_eventstore/queries/event_marker_queries.rbs +21 -0
- data/sig/pg_eventstore/queries/event_queries.rbs +6 -38
- data/sig/pg_eventstore/queries/events_global_index_queries.rbs +37 -0
- data/sig/pg_eventstore/queries/index_filtering_queries.rbs +50 -0
- data/sig/pg_eventstore/queries/links_resolver.rbs +7 -11
- data/sig/pg_eventstore/queries/maintenance_queries.rbs +12 -9
- data/sig/pg_eventstore/queries/partition_queries.rbs +32 -67
- data/sig/pg_eventstore/queries/replica_queries.rbs +31 -0
- data/sig/pg_eventstore/queries/streams_global_index_queries.rbs +39 -0
- data/sig/pg_eventstore/queries/transaction_queries.rbs +4 -2
- data/sig/pg_eventstore/queries.rbs +11 -21
- data/sig/pg_eventstore/query_builders/basic_filtering.rbs +10 -3
- data/sig/pg_eventstore/query_builders/event_markers_filtering.rbs +17 -0
- data/sig/pg_eventstore/query_builders/event_markers_index_filtering.rbs +69 -0
- data/sig/pg_eventstore/query_builders/event_subscription_positions_filtering.rbs +15 -0
- data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +9 -51
- data/sig/pg_eventstore/query_builders/events_global_index_filtering.rbs +68 -0
- data/sig/pg_eventstore/query_builders/filters/collection.rbs +84 -0
- data/sig/pg_eventstore/query_builders/filters/event_type_filter.rbs +19 -0
- data/sig/pg_eventstore/query_builders/filters/filter_row.rbs +21 -0
- data/sig/pg_eventstore/query_builders/filters/marker_filter.rbs +13 -0
- data/sig/pg_eventstore/query_builders/filters/marker_filter_row.rbs +19 -0
- data/sig/pg_eventstore/query_builders/filters/stream_filter.rbs +24 -0
- data/sig/pg_eventstore/query_builders/index_based_events_filtering.rbs +60 -0
- data/sig/pg_eventstore/query_builders/partitions_filtering.rbs +29 -10
- data/sig/pg_eventstore/query_builders/read_cursor/stream_cursor.rbs +47 -0
- data/sig/pg_eventstore/query_builders/streams_global_index_filtering.rbs +27 -0
- data/sig/pg_eventstore/query_builders/subscription_events_filtering.rbs +26 -0
- data/sig/pg_eventstore/query_strategy/async.rbs +17 -0
- data/sig/pg_eventstore/query_strategy/foreground.rbs +11 -0
- data/sig/pg_eventstore/query_strategy.rbs +7 -0
- data/sig/pg_eventstore/raw_event.rbs +20 -0
- data/sig/pg_eventstore/sql_builder.rbs +32 -10
- data/sig/pg_eventstore/stream.rbs +10 -18
- data/sig/pg_eventstore/stream_global_index.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rbs +5 -4
- data/sig/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rbs +9 -0
- data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rbs +17 -12
- data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rbs +16 -8
- data/sig/pg_eventstore/subscriptions/event_subscription_position_queries.rbs +30 -0
- data/sig/pg_eventstore/subscriptions/events_processor.rbs +12 -5
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/multiple.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/replica.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/single.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/events_subscription_position_worker.rbs +28 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +18 -50
- data/sig/pg_eventstore/subscriptions/replica_subscription_handler.rbs +33 -0
- data/sig/pg_eventstore/subscriptions/replica_subscription_runner.rbs +4 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/collection.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/index_read_strategy.rbs +23 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/replication_strategy.rbs +23 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy.rbs +11 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +13 -10
- data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +1 -1
- data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +13 -5
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +5 -5
- data/sig/pg_eventstore/subscriptions/subscriptions_lifecycle.rbs +4 -6
- data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +29 -43
- data/sig/pg_eventstore/synchronized_array.rbs +4 -0
- data/sig/pg_eventstore/utils.rbs +18 -11
- data/sig/pg_eventstore/web/application.rbs +13 -3
- data/sig/pg_eventstore/web/paginator/base_collection.rbs +2 -0
- data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/events_collection.rbs +11 -11
- data/sig/pg_eventstore/web/paginator/helpers.rbs +6 -15
- data/sig/pg_eventstore/web/paginator/markers_collection.rbs +13 -0
- data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/streams_collection.rbs +30 -0
- data/sig/pg_eventstore.rbs +8 -26
- metadata +181 -21
- data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +0 -69
- data/lib/pg_eventstore/commands/regular_stream_read_grouped.rb +0 -31
- data/lib/pg_eventstore/subscriptions/queries/service_queries.rb +0 -73
- data/lib/pg_eventstore/subscriptions/subscription_position_evaluation.rb +0 -195
- data/lib/pg_eventstore/web/views/home/partials/system_stream_filter.erb +0 -15
- data/sig/pg_eventstore/commands/all_stream_read_grouped.rbs +0 -16
- data/sig/pg_eventstore/commands/regular_stream_read_grouped.rbs +0 -8
- data/sig/pg_eventstore/subscriptions/queries/service_queries.rbs +0 -15
- data/sig/pg_eventstore/subscriptions/subscription_position_evaluation.rbs +0 -53
- data/sig/pg_eventstore/subscriptions/synchronized_array.rbs +0 -4
- /data/sig/interfaces/{_raw_event_handler.rbs → raw_event_handler.rbs} +0 -0
data/lib/pg_eventstore/client.rb
CHANGED
|
@@ -20,20 +20,34 @@ module PgEventstore
|
|
|
20
20
|
# @param stream [PgEventstore::Stream]
|
|
21
21
|
# @param events_or_event [PgEventstore::Event, Array<PgEventstore::Event>]
|
|
22
22
|
# @param options [Hash]
|
|
23
|
-
# @option options [Integer] :expected_revision
|
|
23
|
+
# @option options [Integer] :expected_revision expected stream revision
|
|
24
24
|
# @option options [Symbol] :expected_revision provide one of next values: :any, :no_stream or :stream_exists
|
|
25
|
-
# @
|
|
25
|
+
# @option options [Hash<String, Integer>, Hash<String, Symbol>] :expected_revision
|
|
26
|
+
# <even type>-to-<expected stream revision> map. Allows to define expected stream revision at the given event
|
|
27
|
+
# type. Useful when implementing Dynamic Consistency Boundaries
|
|
28
|
+
# @option options [Hash<String, Hash>] :expected_revision <even type>-to-<markers> map. Allows to define expected
|
|
29
|
+
# stream revision at the given event type, scoped to the specific marker(s). Useful when implementing
|
|
30
|
+
# Dynamic Consistency Boundaries
|
|
31
|
+
# @param middlewares [Array<Symbol>, nil] provide a list of middleware names to override a config's middlewares
|
|
26
32
|
# @return [PgEventstore::Event, Array<PgEventstore::Event>] persisted event(s)
|
|
27
33
|
# @raise [PgEventstore::WrongExpectedRevisionError]
|
|
28
34
|
def append_to_stream(stream, events_or_event, options: {}, middlewares: nil)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Utils.assert_node_role!(config, Config::NodeRole.writable)
|
|
36
|
+
middlewares = self.middlewares(middlewares)
|
|
37
|
+
event_modifier = Commands::EventModifiers::PrepareRegularEvent.new(EventSerializer.new(middlewares))
|
|
38
|
+
queries = Queries.new(
|
|
39
|
+
partitions: partition_queries,
|
|
40
|
+
events: event_queries,
|
|
41
|
+
transactions: transaction_queries,
|
|
42
|
+
events_global_index: events_global_index_queries,
|
|
43
|
+
streams_global_index: streams_global_index_queries,
|
|
44
|
+
event_subscription_positions: event_subscription_position_queries,
|
|
45
|
+
event_markers: event_marker_queries,
|
|
46
|
+
index_filtering: index_filtering_queries
|
|
47
|
+
)
|
|
48
|
+
result = Commands::Append.new(queries).call(
|
|
49
|
+
stream, *events_or_event, event_modifier:, deserializer: event_deserializer(middlewares), options:
|
|
50
|
+
)
|
|
37
51
|
events_or_event.is_a?(Array) ? result : result.first
|
|
38
52
|
end
|
|
39
53
|
|
|
@@ -47,9 +61,11 @@ module PgEventstore
|
|
|
47
61
|
# PgEventstore.client.append_to_stream(...)
|
|
48
62
|
# end
|
|
49
63
|
#
|
|
64
|
+
# @param read_only [Boolean] whether transaction is read-only. Running mutation queries within read-only transaction
|
|
65
|
+
# will result in exception
|
|
50
66
|
# @return the result of the given block
|
|
51
|
-
def multiple(&
|
|
52
|
-
Commands::Multiple.new(Queries.new(transactions: transaction_queries)).call(&
|
|
67
|
+
def multiple(read_only: false, &)
|
|
68
|
+
Commands::Multiple.new(Queries.new(transactions: transaction_queries)).call(read_only:, &)
|
|
53
69
|
end
|
|
54
70
|
|
|
55
71
|
# Read events from the specific stream or from "all" stream.
|
|
@@ -59,16 +75,22 @@ module PgEventstore
|
|
|
59
75
|
# :asc, :desc
|
|
60
76
|
# @option options [Integer] :from_revision a starting revision number. **Use this option when stream name is a
|
|
61
77
|
# normal stream name**
|
|
78
|
+
# @option options [Integer] :to_revision ending revision number. **Use this option when stream name is a
|
|
79
|
+
# normal stream name**
|
|
62
80
|
# @option options [Integer] :from_position a starting global position number. **Use this option when reading
|
|
63
81
|
# from "all" stream**
|
|
82
|
+
# @option options [Integer] :to_position ending global position number. **Use this option when reading from
|
|
83
|
+
# "all" stream**
|
|
64
84
|
# @option options [Integer] :max_count max number of events to return in one response. Defaults to config.max_count
|
|
65
85
|
# @option options [Boolean] :resolve_link_tos When using projections to create new events you
|
|
66
86
|
# can set whether the generated events are pointers to existing events. Setting this option to true tells
|
|
67
87
|
# PgEventstore to return the original event instead a link event.
|
|
68
|
-
# @option options [Hash] :filter provide it to filter events. You can filter by: stream
|
|
69
|
-
# by stream is only available when reading from "all" stream.
|
|
70
|
-
#
|
|
71
|
-
#
|
|
88
|
+
# @option options [Hash] :filter provide it to filter events. You can filter by: stream, event type and event
|
|
89
|
+
# markers. Filtering by stream is only available when reading from "all" stream.
|
|
90
|
+
# Basically, you can mix almost all combinations of stream attributes, event types and markers. That are some
|
|
91
|
+
# limitations, though. Please refer to docs/reading_events.md for details.
|
|
92
|
+
# Here are some examples:
|
|
93
|
+
# # Filtering by stream's context. This will return all events which #context is 'User'
|
|
72
94
|
# PgEventstore.client.read(
|
|
73
95
|
# PgEventstore::Stream.all_stream,
|
|
74
96
|
# options: { filter: { streams: [{ context: 'User' }] } }
|
|
@@ -103,42 +125,92 @@ module PgEventstore
|
|
|
103
125
|
#
|
|
104
126
|
# # Filtering by specific event when reading from the specific stream
|
|
105
127
|
# PgEventstore.client.read(stream, options: { filter: { event_types: ['MyAwesomeEvent'] } })
|
|
106
|
-
#
|
|
128
|
+
#
|
|
129
|
+
# # Filtering a specific stream by event markers
|
|
130
|
+
# PgEventstore.client.read(stream, options: { filter: { event_types: [{ markers: ['foo'] }] } })
|
|
131
|
+
#
|
|
132
|
+
# # Filtering a specific stream by event type with markers and event types
|
|
133
|
+
# PgEventstore.client.read(
|
|
134
|
+
# stream, options: { filter: { event_types: [{ type: 'Foo', markers: ['foo'] }, 'Bar'] } }
|
|
135
|
+
# )
|
|
136
|
+
#
|
|
137
|
+
# # Filtering all events by markers
|
|
138
|
+
# PgEventstore.client.read(
|
|
139
|
+
# PgEventstore::Stream.all_stream, options: { filter: { event_types: [{ markers: ['foo'] }] } }
|
|
140
|
+
# )
|
|
141
|
+
# @param middlewares [Array<Symbol>, nil] provide a list of middleware names to override a config's middlewares
|
|
107
142
|
# @return [Array<PgEventstore::Event>]
|
|
108
143
|
# @raise [PgEventstore::StreamNotFoundError]
|
|
109
144
|
def read(stream, options: {}, middlewares: nil)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
145
|
+
queries = Queries.new(
|
|
146
|
+
index_filtering: index_filtering_queries,
|
|
147
|
+
streams_global_index: streams_global_index_queries
|
|
148
|
+
)
|
|
149
|
+
Commands::Read.new(queries).call(
|
|
150
|
+
stream,
|
|
151
|
+
deserializer: event_deserializer(middlewares(middlewares)),
|
|
152
|
+
options: { max_count: config.max_count }.merge(options)
|
|
153
|
+
)
|
|
113
154
|
end
|
|
114
155
|
|
|
115
156
|
# @see {#read} for the detailed docs
|
|
116
157
|
# @param stream [PgEventstore::Stream]
|
|
117
158
|
# @param options [Hash] request options
|
|
118
|
-
# @param middlewares [Array
|
|
119
|
-
# @return [Enumerator] enumerator will yield PgEventstore::Event
|
|
159
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
160
|
+
# @return [Enumerator] enumerator will yield Array<PgEventstore::Event>
|
|
120
161
|
def read_paginated(stream, options: {}, middlewares: nil)
|
|
121
162
|
cmd_class = stream.system? ? Commands::SystemStreamReadPaginated : Commands::RegularStreamReadPaginated
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
163
|
+
queries = Queries.new(
|
|
164
|
+
index_filtering: index_filtering_queries,
|
|
165
|
+
streams_global_index: streams_global_index_queries
|
|
166
|
+
)
|
|
167
|
+
cmd_class.new(queries).call(
|
|
168
|
+
stream,
|
|
169
|
+
deserializer: event_deserializer(middlewares(middlewares)),
|
|
170
|
+
options: { max_count: config.max_count }.merge(options)
|
|
171
|
+
)
|
|
125
172
|
end
|
|
126
173
|
|
|
127
|
-
# Takes a stream,
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
174
|
+
# Takes a stream, event types filter and returns most recent(or very first - depending on :direction option) events,
|
|
175
|
+
# one of each given type. The result size is almost always less than or equal to event types list size, so passing
|
|
176
|
+
# :max_count option does not take any effect. In case if event of same type appears in different context/stream
|
|
177
|
+
# name - it will be counted as a different event, thus, may appear several times in the result, scoped to each
|
|
178
|
+
# context and stream name in the result. Useful when implementing Dynamic Consistency Boundaries.
|
|
132
179
|
# @see {#read} for the detailed docs
|
|
133
180
|
# @param stream [PgEventstore::Stream]
|
|
134
181
|
# @param options [Hash] request options
|
|
135
|
-
# @param middlewares [Array
|
|
182
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
136
183
|
# @return [Array<PgEventstore::Event>]
|
|
137
184
|
def read_grouped(stream, options: {}, middlewares: nil)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
185
|
+
queries = Queries.new(
|
|
186
|
+
index_filtering: index_filtering_queries,
|
|
187
|
+
streams_global_index: streams_global_index_queries
|
|
188
|
+
)
|
|
189
|
+
Commands::ReadGrouped.new(queries).call(
|
|
190
|
+
stream, deserializer: event_deserializer(middlewares(middlewares)), options:
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# @param options [Hash] request options
|
|
195
|
+
# @option options [String] :direction read direction. Allowed values are "Forwards", "Backwards", "asc", "desc",
|
|
196
|
+
# :asc, :desc
|
|
197
|
+
# @option options [Integer] :from_position a starting global position number
|
|
198
|
+
# @option options [Integer] :max_count max number of streams to return in one response. Defaults to config.max_count
|
|
199
|
+
# @return [Array<PgEventstore::Stream>]
|
|
200
|
+
def read_streams(options: {})
|
|
201
|
+
queries = Queries.new(streams_global_index: streams_global_index_queries)
|
|
202
|
+
Commands::ReadStreams.new(queries).call(options: { max_count: config.max_count }.merge(options))
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# @param options [Hash] request options
|
|
206
|
+
# @option options [String] :direction read direction. Allowed values are "Forwards", "Backwards", "asc", "desc",
|
|
207
|
+
# :asc, :desc
|
|
208
|
+
# @option options [Integer] :from_position a starting global position number
|
|
209
|
+
# @option options [Integer] :max_count max number of streams to yield. Defaults to config.max_count
|
|
210
|
+
# @return [Enumerator] yields Array<PgEventstore::Stream>
|
|
211
|
+
def read_streams_paginated(options: {})
|
|
212
|
+
queries = Queries.new(streams_global_index: streams_global_index_queries)
|
|
213
|
+
Commands::ReadStreamsPaginated.new(queries).call(options: { max_count: config.max_count }.merge(options))
|
|
142
214
|
end
|
|
143
215
|
|
|
144
216
|
# Links event from one stream into another stream. You can later access it by providing :resolve_link_tos option
|
|
@@ -148,25 +220,42 @@ module PgEventstore
|
|
|
148
220
|
# @param options [Hash]
|
|
149
221
|
# @option options [Integer] :expected_revision provide your own revision number
|
|
150
222
|
# @option options [Symbol] :expected_revision provide one of next values: :any, :no_stream or :stream_exists
|
|
151
|
-
# @param middlewares [Array] provide a list of middleware names to use. Defaults to empty array, meaning no
|
|
223
|
+
# @param middlewares [Array<Symbol>] provide a list of middleware names to use. Defaults to empty array, meaning no
|
|
152
224
|
# middlewares will be applied to the "link" event
|
|
153
225
|
# @return [PgEventstore::Event, Array<PgEventstore::Event>] persisted event(s)
|
|
154
226
|
# @raise [PgEventstore::WrongExpectedRevisionError]
|
|
155
227
|
def link_to(stream, events_or_event, options: {}, middlewares: [])
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
228
|
+
Utils.assert_node_role!(config, Config::NodeRole.writable)
|
|
229
|
+
middlewares = self.middlewares(middlewares)
|
|
230
|
+
event_modifier = Commands::EventModifiers::PrepareLinkEvent.new(
|
|
231
|
+
partition_queries, EventSerializer.new(middlewares)
|
|
232
|
+
)
|
|
233
|
+
queries = Queries.new(
|
|
234
|
+
partitions: partition_queries,
|
|
235
|
+
events: event_queries,
|
|
236
|
+
transactions: transaction_queries,
|
|
237
|
+
events_global_index: events_global_index_queries,
|
|
238
|
+
streams_global_index: streams_global_index_queries,
|
|
239
|
+
event_subscription_positions: event_subscription_position_queries,
|
|
240
|
+
event_markers: event_marker_queries,
|
|
241
|
+
index_filtering: index_filtering_queries
|
|
242
|
+
)
|
|
243
|
+
result = Commands::LinkTo.new(queries).call(
|
|
244
|
+
stream, *events_or_event, event_modifier:, deserializer: event_deserializer(middlewares), options:
|
|
245
|
+
)
|
|
164
246
|
events_or_event.is_a?(Array) ? result : result.first
|
|
165
247
|
end
|
|
166
248
|
|
|
249
|
+
# @param stream [PgEventstore::Stream]
|
|
250
|
+
# @return [Integer]
|
|
251
|
+
def stream_revision(stream)
|
|
252
|
+
queries = Queries.new(streams_global_index: streams_global_index_queries)
|
|
253
|
+
Commands::StreamRevision.new(queries).call(stream)
|
|
254
|
+
end
|
|
255
|
+
|
|
167
256
|
private
|
|
168
257
|
|
|
169
|
-
# @param middlewares [Array
|
|
258
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
170
259
|
# @return [Array<PgEventstore::Middleware>]
|
|
171
260
|
def middlewares(middlewares = nil)
|
|
172
261
|
return config.middlewares.values unless middlewares
|
|
@@ -189,14 +278,40 @@ module PgEventstore
|
|
|
189
278
|
TransactionQueries.new(connection)
|
|
190
279
|
end
|
|
191
280
|
|
|
192
|
-
# @param middlewares [Array<Object<#serialize, #deserialize>>]
|
|
193
281
|
# @return [PgEventstore::EventQueries]
|
|
194
|
-
def event_queries
|
|
195
|
-
EventQueries.new(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
282
|
+
def event_queries
|
|
283
|
+
EventQueries.new(connection)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# @param middlewares [Array<Middleware>]
|
|
287
|
+
# @return [PgEventstore::EventDeserializer]
|
|
288
|
+
def event_deserializer(middlewares)
|
|
289
|
+
EventDeserializer.new(middlewares, config.event_class_resolver)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# @return [PgEventstore::EventsGlobalIndexQueries]
|
|
293
|
+
def events_global_index_queries
|
|
294
|
+
EventsGlobalIndexQueries.new(connection, QueryStrategy::Foreground.new(connection))
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# @return [PgEventstore::StreamsGlobalIndexQueries]
|
|
298
|
+
def streams_global_index_queries
|
|
299
|
+
StreamsGlobalIndexQueries.new(connection, QueryStrategy::Foreground.new(connection))
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# @return [PgEventstore::EventSubscriptionPositionQueries]
|
|
303
|
+
def event_subscription_position_queries
|
|
304
|
+
EventSubscriptionPositionQueries.new(connection)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# @return [PgEventstore::EventMarkerQueries]
|
|
308
|
+
def event_marker_queries
|
|
309
|
+
EventMarkerQueries.new(connection, QueryStrategy::Foreground.new(connection))
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# @return [PgEventstore::IndexFilteringQueries]
|
|
313
|
+
def index_filtering_queries
|
|
314
|
+
IndexFilteringQueries.new(connection, QueryStrategy::Foreground.new(connection))
|
|
200
315
|
end
|
|
201
316
|
end
|
|
202
317
|
end
|
|
@@ -1,71 +1,90 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'revision_check/stream_revision_check'
|
|
4
|
+
|
|
3
5
|
module PgEventstore
|
|
4
6
|
module Commands
|
|
5
7
|
# @!visibility private
|
|
6
8
|
class Append < AbstractCommand
|
|
7
9
|
# @param stream [PgEventstore::Stream]
|
|
8
10
|
# @param events [Array<PgEventstore::Event>]
|
|
11
|
+
# @param event_modifier [#call]
|
|
12
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
9
13
|
# @param options [Hash]
|
|
10
14
|
# @option options [Integer] :expected_revision provide your own revision number
|
|
11
15
|
# @option options [Symbol] :expected_revision provide one of next values: :any, :no_stream or :stream_exists
|
|
12
|
-
# @param event_modifier [#call]
|
|
13
16
|
# @return [Array<PgEventstore::Event>] persisted events
|
|
14
17
|
# @raise [PgEventstore::WrongExpectedRevisionError]
|
|
15
|
-
def call(stream, *events, options: {}
|
|
18
|
+
def call(stream, *events, event_modifier:, deserializer:, options: {})
|
|
16
19
|
raise SystemStreamError, stream if stream.system?
|
|
20
|
+
raise ArgumentError, 'No events to append.' if events.empty?
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
events = events.map(&event_modifier.method(:call))
|
|
23
|
+
markers = events.flat_map { _1.markers + feature_markers(_1) }.uniq
|
|
24
|
+
raw_events = queries.transactions.transaction(:repeatable_read) do
|
|
25
|
+
revision_to_marker_ids_map = {}
|
|
26
|
+
partitions = prepare_partitions(stream, events)
|
|
27
|
+
markers_map = queries.event_markers.find_or_create_by(markers).to_h { [_1.name, _1.id] } if markers.any?
|
|
28
|
+
stream_index = queries.streams_global_index.find_or_create_by(stream)
|
|
29
|
+
revision = stream_index.stream_revision
|
|
30
|
+
expected_revision = RevisionCheck::ExpectedRevision.build(options[:expected_revision])
|
|
31
|
+
current_revision = RevisionCheck::CurrentRevision.build(
|
|
32
|
+
stream, revision, expected_revision, queries.index_filtering
|
|
33
|
+
)
|
|
34
|
+
RevisionCheck::StreamRevisionCheck.assert_eq!(current_revision, expected_revision, stream)
|
|
35
|
+
events.each.with_index(1) do |event, index|
|
|
36
|
+
event.stream_revision = revision + index
|
|
37
|
+
event.markers.each do |event_marker|
|
|
38
|
+
revision_to_marker_ids_map[revision + index] ||= Set.new
|
|
39
|
+
revision_to_marker_ids_map[revision + index].add(markers_map[event_marker])
|
|
40
|
+
end
|
|
41
|
+
event.feature_markers.each do |feature_marker|
|
|
42
|
+
revision_to_marker_ids_map[revision + index] ||= Set.new
|
|
43
|
+
revision_to_marker_ids_map[revision + index].add(markers_map[feature_marker.marker])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
revision += events.size
|
|
47
|
+
queries.events.insert(stream, events).tap do |created_events|
|
|
48
|
+
stream_idx_attrs_to_update = { stream_revision: revision }
|
|
49
|
+
if stream_index.starting_position == StreamGlobalIndex::INITIAL_STARTING_POSITION
|
|
50
|
+
stream_idx_attrs_to_update[:starting_position] = created_events.first['global_position']
|
|
51
|
+
end
|
|
52
|
+
queries.streams_global_index.update(stream_index.id, **stream_idx_attrs_to_update)
|
|
53
|
+
write_api_events_idx = queries.events_global_index.index_events(created_events, partitions, stream_index.id)
|
|
54
|
+
queries.event_subscription_positions.create_unprocessed_positions(created_events)
|
|
55
|
+
if markers.any?
|
|
56
|
+
queries.event_markers.create_indexes(
|
|
57
|
+
stream_index.id, write_api_events_idx, revision_to_marker_ids_map
|
|
58
|
+
)
|
|
59
|
+
end
|
|
23
60
|
end
|
|
24
|
-
create_partitions(stream, formatted_events)
|
|
25
|
-
queries.events.insert(stream, formatted_events)
|
|
26
61
|
end
|
|
62
|
+
# It is important to return events in the form they were persisted into the database instead passing them
|
|
63
|
+
# through the configured middlewares
|
|
64
|
+
deserializer.deserialize_many(raw_events)
|
|
27
65
|
end
|
|
28
66
|
|
|
29
67
|
private
|
|
30
68
|
|
|
31
|
-
# @param
|
|
32
|
-
# @
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
missing_event_types = events.map(&:type).map(&:to_s).uniq.select do |event_type|
|
|
36
|
-
queries.partitions.partition_required?(stream, event_type)
|
|
37
|
-
end
|
|
38
|
-
raise MissingPartitions.new(stream, missing_event_types) if missing_event_types.any?
|
|
69
|
+
# @param event [PgEventstore::Event]
|
|
70
|
+
# @return [Array<String>]
|
|
71
|
+
def feature_markers(event)
|
|
72
|
+
event.feature_markers.map(&:marker)
|
|
39
73
|
end
|
|
40
74
|
|
|
41
|
-
# @param revision [Integer]
|
|
42
|
-
# @param expected_revision [Symbol, Integer]
|
|
43
75
|
# @param stream [PgEventstore::Stream]
|
|
44
|
-
# @
|
|
45
|
-
# @return [
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
end
|
|
76
|
+
# @param events [Array<PgEventstore::Event>]
|
|
77
|
+
# @return [Array<PgEventstore::Partition>]
|
|
78
|
+
def prepare_partitions(stream, events)
|
|
79
|
+
event_types = events.map { _1.type.to_s }.uniq
|
|
80
|
+
filter_collection = QueryBuilders::Filters::Collection.from_options(
|
|
81
|
+
{ filter: { streams: [{ context: stream.context, stream_name: stream.stream_name }], event_types: } }
|
|
82
|
+
)
|
|
83
|
+
existing_partitions = queries.partitions.partitions(filter_collection)
|
|
84
|
+
missing_event_types = event_types - existing_partitions.map(&:event_type)
|
|
85
|
+
raise MissingPartitions.new(stream, missing_event_types) if missing_event_types.any?
|
|
56
86
|
|
|
57
|
-
|
|
58
|
-
if revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :stream_exists
|
|
59
|
-
raise WrongExpectedRevisionError.new(
|
|
60
|
-
revision: revision, expected_revision: expected_revision, stream: stream
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
if revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
|
|
64
|
-
raise WrongExpectedRevisionError.new(
|
|
65
|
-
revision: revision, expected_revision: expected_revision, stream: stream
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
87
|
+
existing_partitions
|
|
69
88
|
end
|
|
70
89
|
end
|
|
71
90
|
end
|
|
@@ -13,15 +13,14 @@ module PgEventstore
|
|
|
13
13
|
# @param force [Boolean]
|
|
14
14
|
# @return [Boolean]
|
|
15
15
|
def call(event, force:)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
next false unless event
|
|
16
|
+
raise ArgumentError, "Event#stream is nil: #{event.inspect}" unless event.stream
|
|
17
|
+
return false if queries.events_global_index.global_positions_from_db([event]).empty?
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
check_records_number_to_lock(event) unless force
|
|
20
|
+
queries.maintenance.delete_event(event)
|
|
21
|
+
true
|
|
22
|
+
rescue RecordNotFound
|
|
23
|
+
false
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
private
|
|
@@ -9,9 +9,9 @@ module PgEventstore
|
|
|
9
9
|
def call(stream)
|
|
10
10
|
raise SystemStreamError, stream if stream.system?
|
|
11
11
|
|
|
12
|
-
queries.
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
queries.maintenance.delete_stream(stream) > 0
|
|
13
|
+
rescue RecordNotFound
|
|
14
|
+
false
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -9,20 +9,25 @@ module PgEventstore
|
|
|
9
9
|
attr_reader :partition_queries, :partitions
|
|
10
10
|
|
|
11
11
|
# @param partition_queries [PgEventstore::PartitionQueries]
|
|
12
|
-
|
|
12
|
+
# @param serializer [PgEventstore::EventSerializer]
|
|
13
|
+
def initialize(partition_queries, serializer)
|
|
13
14
|
@partitions = {}
|
|
14
15
|
@partition_queries = partition_queries
|
|
16
|
+
@serializer = serializer
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
# @param event [PgEventstore::Event]
|
|
18
|
-
# @param revision [Integer]
|
|
19
20
|
# @return [PgEventstore::Event]
|
|
20
|
-
def call(event
|
|
21
|
-
Event.new(
|
|
22
|
-
|
|
21
|
+
def call(event)
|
|
22
|
+
event = Event.new(
|
|
23
|
+
link_global_position: event.global_position,
|
|
24
|
+
link_partition_id: partition_id(event),
|
|
25
|
+
type: Event::LINK_TYPE
|
|
23
26
|
).tap do |e|
|
|
24
|
-
%i[
|
|
27
|
+
%i[link_global_position link_partition_id type].each { |attr| e.readonly!(attr) }
|
|
25
28
|
end
|
|
29
|
+
@serializer.serialize(event)
|
|
30
|
+
event
|
|
26
31
|
end
|
|
27
32
|
|
|
28
33
|
private
|
|
@@ -6,15 +6,20 @@ module PgEventstore
|
|
|
6
6
|
# Defines how to transform regular event before appending it to the stream
|
|
7
7
|
# @!visibility private
|
|
8
8
|
class PrepareRegularEvent
|
|
9
|
+
# @param serializer [PgEventstore::EventSerializer]
|
|
10
|
+
def initialize(serializer)
|
|
11
|
+
@serializer = serializer
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
# @param event [PgEventstore::Event]
|
|
10
|
-
# @param revision [Integer]
|
|
11
15
|
# @return [PgEventstore::Event]
|
|
12
|
-
def call(event
|
|
13
|
-
event.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
def call(event)
|
|
17
|
+
event = event.dup
|
|
18
|
+
event.link_global_position = nil
|
|
19
|
+
event.link_partition_id = nil
|
|
20
|
+
%i[link_global_position link_partition_id].each { |attr| event.readonly!(attr) }
|
|
21
|
+
@serializer.serialize(event)
|
|
22
|
+
event
|
|
18
23
|
end
|
|
19
24
|
end
|
|
20
25
|
end
|
|
@@ -6,32 +6,32 @@ module PgEventstore
|
|
|
6
6
|
class LinkTo < AbstractCommand
|
|
7
7
|
# @param stream [PgEventstore::Stream]
|
|
8
8
|
# @param events [Array<PgEventstore::Event>]
|
|
9
|
+
# @param event_modifier [#call]
|
|
10
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
9
11
|
# @param options [Hash]
|
|
10
12
|
# @option options [Integer] :expected_revision provide your own revision number
|
|
11
13
|
# @option options [Symbol] :expected_revision provide one of next values: :any, :no_stream or :stream_exists
|
|
12
14
|
# @return [Array<PgEventstore::Event>] persisted events
|
|
13
15
|
# @raise [PgEventstore::WrongExpectedRevisionError]
|
|
14
16
|
# @raise [PgEventstore::NotPersistedEventError]
|
|
15
|
-
def call(stream, *events, options: {})
|
|
17
|
+
def call(stream, *events, event_modifier:, deserializer:, options: {})
|
|
16
18
|
check_events_presence(events)
|
|
17
19
|
append_cmd = Append.new(queries)
|
|
18
|
-
append_cmd.call(
|
|
19
|
-
stream, *events, options: options, event_modifier: EventModifiers::PrepareLinkEvent.new(queries.partitions)
|
|
20
|
-
)
|
|
20
|
+
append_cmd.call(stream, *events, event_modifier:, deserializer:, options:)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
|
-
# Checks if the given events are persisted events. This is needed to prevent potentially non-existing
|
|
26
|
-
# from appearing in #
|
|
25
|
+
# Checks if the given events are persisted events. This is needed to prevent potentially non-existing
|
|
26
|
+
# global_position values from appearing in #link_global_position column.
|
|
27
27
|
# @param events [Array<PgEventstore::Event>]
|
|
28
28
|
# @return [void]
|
|
29
29
|
def check_events_presence(events)
|
|
30
|
-
|
|
31
|
-
missing_ids = events.map(&:
|
|
30
|
+
global_positions_from_db = queries.events_global_index.global_positions_from_db(events)
|
|
31
|
+
missing_ids = events.map(&:global_position) - global_positions_from_db
|
|
32
32
|
return if missing_ids.empty?
|
|
33
33
|
|
|
34
|
-
missing_event = events.find { |event| event.
|
|
34
|
+
missing_event = events.find { |event| event.global_position == missing_ids.first }
|
|
35
35
|
raise NotPersistedEventError, missing_event
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -5,19 +5,37 @@ module PgEventstore
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
class Read < AbstractCommand
|
|
7
7
|
# @param stream [PgEventstore::Stream]
|
|
8
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
8
9
|
# @param options [Hash] request options
|
|
9
10
|
# @option options [String] :direction read direction - 'Forwards' or 'Backwards'
|
|
10
|
-
# @option options [Integer
|
|
11
|
-
# @option options [Integer
|
|
11
|
+
# @option options [Integer] :from_revision. **Use this option when stream is a regular stream**
|
|
12
|
+
# @option options [Integer] :from_position. **Use this option when reading from "all" stream**
|
|
13
|
+
# @option options [Integer] :to_revision. **Use this option when stream is a regular stream**
|
|
14
|
+
# @option options [Integer] :to_position. **Use this option when reading from "all" stream**
|
|
12
15
|
# @option options [Integer] :max_count
|
|
13
16
|
# @option options [Boolean] :resolve_link_tos
|
|
14
17
|
# @option options [Hash] :filter provide it to filter events
|
|
15
18
|
# @return [Array<PgEventstore::Event>]
|
|
16
19
|
# @raise [PgEventstore::StreamNotFoundError]
|
|
17
|
-
def call(stream, options: {})
|
|
18
|
-
queries.
|
|
20
|
+
def call(stream, deserializer:, options: {})
|
|
21
|
+
queries.streams_global_index.stream_exists?(stream) || raise(StreamNotFoundError, stream) unless stream.system?
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
filter_collection = QueryBuilders::Filters::Collection.from_stream_and_options(stream, options)
|
|
24
|
+
cursor = QueryBuilders::ReadCursor::StreamCursor.from_stream_and_options(stream, options)
|
|
25
|
+
raise NotSupportedError, '#read does not support look up by prefix.' if filter_collection.has_prefix_filter?
|
|
26
|
+
|
|
27
|
+
if filter_collection.has_incomplete_markers_filter? && filter_collection.has_incomplete_stream_filter?
|
|
28
|
+
error_message = <<~TEXT.strip
|
|
29
|
+
#read does not support look up by context/context & stream name and markers filter without specifying \
|
|
30
|
+
event type explicitly. Please add specific event type to your markers filter. \
|
|
31
|
+
Example: { filter: { event_types: [{ type: 'Foo', markers: ['foo', 'bar'] }] } }
|
|
32
|
+
TEXT
|
|
33
|
+
raise NotSupportedError, error_message
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
indexes = queries.index_filtering.fetch_indexes_for_read_api(filter_collection, cursor)
|
|
37
|
+
repo = queries.index_filtering.compute_read_api_chunks_repo(indexes, options[:resolve_link_tos] || false)
|
|
38
|
+
deserializer.deserialize_many(repo.consume_all)
|
|
21
39
|
end
|
|
22
40
|
end
|
|
23
41
|
end
|