pg_eventstore 2.0.0 → 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 +10 -1
- data/CHANGELOG.md +186 -20
- data/README.md +25 -15
- data/db/migrations/10_setup_pg_cron.rb +1 -23
- 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/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 +17 -8
- 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/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/client.rb +163 -50
- 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 +9 -7
- data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
- data/lib/pg_eventstore/commands/link_to.rb +5 -5
- 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 +21 -2
- data/lib/pg_eventstore/errors.rb +136 -10
- data/lib/pg_eventstore/event.rb +34 -2
- 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 +2 -2
- 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 +7 -93
- 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 +4 -4
- data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
- data/lib/pg_eventstore/queries/partition_queries.rb +45 -103
- 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 +52 -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 +13 -16
- data/lib/pg_eventstore/stream_global_index.rb +28 -0
- 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 +12 -0
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +21 -7
- data/lib/pg_eventstore/subscriptions/events_processor.rb +20 -18
- 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_queries.rb +78 -54
- 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 +2 -1
- 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 +24 -0
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +4 -2
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -9
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
- data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +9 -18
- data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +74 -14
- data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
- data/lib/pg_eventstore/tasks/setup.rake +2 -2
- data/lib/pg_eventstore/utils.rb +31 -0
- data/lib/pg_eventstore/version.rb +1 -1
- data/lib/pg_eventstore/web/application.rb +100 -16
- 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 +16 -9
- 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/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 +23 -60
- 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 +40 -42
- 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/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 +16 -2
- 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/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 +4 -36
- 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 +5 -9
- 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 +2 -0
- 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 +17 -6
- 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 +7 -39
- 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 -2
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +1 -8
- 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 +10 -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 +175 -20
- data/Dockerfile +0 -3
- 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/subscription_service_queries.rb +0 -78
- 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/subscription_service_queries.rbs +0 -19
- 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
|
|
|
@@ -61,16 +75,22 @@ module PgEventstore
|
|
|
61
75
|
# :asc, :desc
|
|
62
76
|
# @option options [Integer] :from_revision a starting revision number. **Use this option when stream name is a
|
|
63
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**
|
|
64
80
|
# @option options [Integer] :from_position a starting global position number. **Use this option when reading
|
|
65
81
|
# from "all" stream**
|
|
82
|
+
# @option options [Integer] :to_position ending global position number. **Use this option when reading from
|
|
83
|
+
# "all" stream**
|
|
66
84
|
# @option options [Integer] :max_count max number of events to return in one response. Defaults to config.max_count
|
|
67
85
|
# @option options [Boolean] :resolve_link_tos When using projections to create new events you
|
|
68
86
|
# can set whether the generated events are pointers to existing events. Setting this option to true tells
|
|
69
87
|
# PgEventstore to return the original event instead a link event.
|
|
70
|
-
# @option options [Hash] :filter provide it to filter events. You can filter by: stream
|
|
71
|
-
# by stream is only available when reading from "all" stream.
|
|
72
|
-
#
|
|
73
|
-
#
|
|
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'
|
|
74
94
|
# PgEventstore.client.read(
|
|
75
95
|
# PgEventstore::Stream.all_stream,
|
|
76
96
|
# options: { filter: { streams: [{ context: 'User' }] } }
|
|
@@ -105,42 +125,92 @@ module PgEventstore
|
|
|
105
125
|
#
|
|
106
126
|
# # Filtering by specific event when reading from the specific stream
|
|
107
127
|
# PgEventstore.client.read(stream, options: { filter: { event_types: ['MyAwesomeEvent'] } })
|
|
108
|
-
#
|
|
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
|
|
109
142
|
# @return [Array<PgEventstore::Event>]
|
|
110
143
|
# @raise [PgEventstore::StreamNotFoundError]
|
|
111
144
|
def read(stream, options: {}, middlewares: nil)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
+
)
|
|
115
154
|
end
|
|
116
155
|
|
|
117
156
|
# @see {#read} for the detailed docs
|
|
118
157
|
# @param stream [PgEventstore::Stream]
|
|
119
158
|
# @param options [Hash] request options
|
|
120
|
-
# @param middlewares [Array
|
|
121
|
-
# @return [Enumerator] enumerator will yield PgEventstore::Event
|
|
159
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
160
|
+
# @return [Enumerator] enumerator will yield Array<PgEventstore::Event>
|
|
122
161
|
def read_paginated(stream, options: {}, middlewares: nil)
|
|
123
162
|
cmd_class = stream.system? ? Commands::SystemStreamReadPaginated : Commands::RegularStreamReadPaginated
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
+
)
|
|
127
172
|
end
|
|
128
173
|
|
|
129
|
-
# Takes a stream,
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
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.
|
|
134
179
|
# @see {#read} for the detailed docs
|
|
135
180
|
# @param stream [PgEventstore::Stream]
|
|
136
181
|
# @param options [Hash] request options
|
|
137
|
-
# @param middlewares [Array
|
|
182
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
138
183
|
# @return [Array<PgEventstore::Event>]
|
|
139
184
|
def read_grouped(stream, options: {}, middlewares: nil)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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))
|
|
144
214
|
end
|
|
145
215
|
|
|
146
216
|
# Links event from one stream into another stream. You can later access it by providing :resolve_link_tos option
|
|
@@ -150,25 +220,42 @@ module PgEventstore
|
|
|
150
220
|
# @param options [Hash]
|
|
151
221
|
# @option options [Integer] :expected_revision provide your own revision number
|
|
152
222
|
# @option options [Symbol] :expected_revision provide one of next values: :any, :no_stream or :stream_exists
|
|
153
|
-
# @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
|
|
154
224
|
# middlewares will be applied to the "link" event
|
|
155
225
|
# @return [PgEventstore::Event, Array<PgEventstore::Event>] persisted event(s)
|
|
156
226
|
# @raise [PgEventstore::WrongExpectedRevisionError]
|
|
157
227
|
def link_to(stream, events_or_event, options: {}, middlewares: [])
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
+
)
|
|
166
246
|
events_or_event.is_a?(Array) ? result : result.first
|
|
167
247
|
end
|
|
168
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
|
+
|
|
169
256
|
private
|
|
170
257
|
|
|
171
|
-
# @param middlewares [Array
|
|
258
|
+
# @param middlewares [Array<Symbol>, nil]
|
|
172
259
|
# @return [Array<PgEventstore::Middleware>]
|
|
173
260
|
def middlewares(middlewares = nil)
|
|
174
261
|
return config.middlewares.values unless middlewares
|
|
@@ -191,14 +278,40 @@ module PgEventstore
|
|
|
191
278
|
TransactionQueries.new(connection)
|
|
192
279
|
end
|
|
193
280
|
|
|
194
|
-
# @param middlewares [Array<Object<#serialize, #deserialize>>]
|
|
195
281
|
# @return [PgEventstore::EventQueries]
|
|
196
|
-
def event_queries
|
|
197
|
-
EventQueries.new(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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))
|
|
202
315
|
end
|
|
203
316
|
end
|
|
204
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:, expected_revision:, stream:
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
if revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
|
|
64
|
-
raise WrongExpectedRevisionError.new(
|
|
65
|
-
revision:, expected_revision:, 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,23 +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(
|
|
21
|
+
def call(event)
|
|
22
|
+
event = Event.new(
|
|
22
23
|
link_global_position: event.global_position,
|
|
23
24
|
link_partition_id: partition_id(event),
|
|
24
|
-
type: Event::LINK_TYPE
|
|
25
|
-
stream_revision: revision
|
|
25
|
+
type: Event::LINK_TYPE
|
|
26
26
|
).tap do |e|
|
|
27
|
-
%i[link_global_position link_partition_id type
|
|
27
|
+
%i[link_global_position link_partition_id type].each { |attr| e.readonly!(attr) }
|
|
28
28
|
end
|
|
29
|
+
@serializer.serialize(event)
|
|
30
|
+
event
|
|
29
31
|
end
|
|
30
32
|
|
|
31
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,18 +6,18 @@ 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:, 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
|
|
@@ -27,7 +27,7 @@ module PgEventstore
|
|
|
27
27
|
# @param events [Array<PgEventstore::Event>]
|
|
28
28
|
# @return [void]
|
|
29
29
|
def check_events_presence(events)
|
|
30
|
-
global_positions_from_db = queries.
|
|
30
|
+
global_positions_from_db = queries.events_global_index.global_positions_from_db(events)
|
|
31
31
|
missing_ids = events.map(&:global_position) - global_positions_from_db
|
|
32
32
|
return if missing_ids.empty?
|
|
33
33
|
|
|
@@ -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
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class ReadGrouped < AbstractCommand
|
|
7
|
+
# @param stream [PgEventstore::Stream]
|
|
8
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
9
|
+
# @param options [Hash] request options
|
|
10
|
+
# @option options [String] :direction read direction - 'Forwards' or 'Backwards'
|
|
11
|
+
# @option options [Integer, Symbol] :from_revision. **Use this option when stream name is a normal stream name**
|
|
12
|
+
# @option options [Integer, Symbol] :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**
|
|
15
|
+
# @option options [Integer] :max_count
|
|
16
|
+
# @option options [Boolean] :resolve_link_tos
|
|
17
|
+
# @option options [Hash] :filter provide it to filter events
|
|
18
|
+
# @return [Array<PgEventstore::Event>]
|
|
19
|
+
# @raise [PgEventstore::StreamNotFoundError]
|
|
20
|
+
def call(stream, deserializer:, options: {})
|
|
21
|
+
filter_collection = QueryBuilders::Filters::Collection.from_stream_and_options(stream, options)
|
|
22
|
+
cursor = QueryBuilders::ReadCursor::StreamCursor.from_stream_and_options(stream, options)
|
|
23
|
+
if filter_collection.has_prefix_filter?
|
|
24
|
+
raise NotSupportedError, '#read_grouped does not support look up by prefix.'
|
|
25
|
+
end
|
|
26
|
+
if !filter_collection.has_event_types? && !filter_collection.has_markers?
|
|
27
|
+
raise ArgumentError, '#read_grouped requires correct :event_types filter.'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if filter_collection.has_incomplete_markers_filter? && filter_collection.has_incomplete_stream_filter?
|
|
31
|
+
error_message = <<~TEXT.strip
|
|
32
|
+
#read_paginated does not support look up by context/context & stream name and markers filter without \
|
|
33
|
+
specifying event type explicitly. Please add specific event type to your markers filter. \
|
|
34
|
+
Example: { filter: { event_types: [{ type: 'Foo', markers: ['foo', 'bar'] }] } }
|
|
35
|
+
TEXT
|
|
36
|
+
raise NotSupportedError, error_message
|
|
37
|
+
end
|
|
38
|
+
queries.streams_global_index.stream_exists?(stream) || raise(StreamNotFoundError, stream) unless stream.system?
|
|
39
|
+
|
|
40
|
+
indexes = queries.index_filtering.fetch_grouped_indexes_for_read_api(filter_collection, cursor)
|
|
41
|
+
repo = queries.index_filtering.compute_read_api_chunks_repo(indexes, options[:resolve_link_tos] || false)
|
|
42
|
+
deserializer.deserialize_many(repo.consume_all)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|