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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class ReadStreams < AbstractCommand
|
|
7
|
+
# @param options [Hash] request options
|
|
8
|
+
# @option options [String] :direction
|
|
9
|
+
# @option options [Integer] :from_position
|
|
10
|
+
# @option options [Integer] :max_count
|
|
11
|
+
# @return [Array<PgEventstore::Stream>]
|
|
12
|
+
def call(options: {})
|
|
13
|
+
indexes = queries.streams_global_index.streams_global_index(options)
|
|
14
|
+
queries.streams_global_index.resolve_indexes(indexes)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class ReadStreamsPaginated < AbstractCommand
|
|
7
|
+
# @param options [Hash] request options
|
|
8
|
+
# @option options [String] :direction
|
|
9
|
+
# @option options [Integer] :from_position
|
|
10
|
+
# @option options [Integer] :max_count
|
|
11
|
+
# @return [Enumerator]
|
|
12
|
+
def call(options: {})
|
|
13
|
+
Enumerator.new do |yielder|
|
|
14
|
+
next_position = nil
|
|
15
|
+
loop do
|
|
16
|
+
options = options.merge(from_position: next_position) if next_position
|
|
17
|
+
indexes = queries.streams_global_index.streams_global_index(options)
|
|
18
|
+
streams = queries.streams_global_index.resolve_indexes(indexes)
|
|
19
|
+
yielder << streams if streams.any?
|
|
20
|
+
if end_reached?(streams, options[:max_count] || QueryBuilders::StreamsGlobalIndexFiltering::DEFAULT_LIMIT)
|
|
21
|
+
raise StopIteration
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
next_position = calc_next_position(indexes, options[:direction])
|
|
25
|
+
raise StopIteration if next_position <= 0
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# @param streams [Array<PgEventstore::Stream>]
|
|
33
|
+
# @param max_count [Integer]
|
|
34
|
+
# @return [Boolean]
|
|
35
|
+
def end_reached?(streams, max_count)
|
|
36
|
+
streams.size < max_count
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param indexes [Array<PgEventstore::StreamGlobalIndex>]
|
|
40
|
+
# @param direction [String, Symbol, nil]
|
|
41
|
+
# @return [Integer]
|
|
42
|
+
def calc_next_position(indexes, direction)
|
|
43
|
+
return indexes.last.starting_position + 1 if forwards?(direction)
|
|
44
|
+
|
|
45
|
+
indexes.last.starting_position - 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param direction [String, Symbol, nil]
|
|
49
|
+
# @return [Boolean]
|
|
50
|
+
def forwards?(direction)
|
|
51
|
+
QueryBuilders::StreamsGlobalIndexFiltering::SQL_DIRECTIONS[direction] ==
|
|
52
|
+
QueryBuilders::StreamsGlobalIndexFiltering::SQL_DIRECTIONS[:asc]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -5,14 +5,14 @@ module PgEventstore
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
class RegularStreamReadPaginated < AbstractCommand
|
|
7
7
|
# @see PgEventstore::Commands::Read for docs
|
|
8
|
-
def call(stream, options: {})
|
|
8
|
+
def call(stream, deserializer:, options: {})
|
|
9
9
|
Enumerator.new do |yielder|
|
|
10
10
|
next_revision = nil
|
|
11
11
|
loop do
|
|
12
12
|
options = options.merge(from_revision: next_revision) if next_revision
|
|
13
|
-
events = read_cmd.call(stream, options:)
|
|
13
|
+
events = read_cmd.call(stream, deserializer:, options:)
|
|
14
14
|
yielder << events if events.any?
|
|
15
|
-
if end_reached?(events, options[:max_count] || QueryBuilders::
|
|
15
|
+
if end_reached?(events, options[:max_count] || QueryBuilders::EventsGlobalIndexFiltering::DEFAULT_LIMIT)
|
|
16
16
|
raise StopIteration
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ module PgEventstore
|
|
|
43
43
|
# @param direction [String, Symbol, nil]
|
|
44
44
|
# @return [Boolean]
|
|
45
45
|
def forwards?(direction)
|
|
46
|
-
QueryBuilders::
|
|
46
|
+
QueryBuilders::BasicFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::BasicFiltering::SQL_DIRECTIONS[:asc]
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# @return [PgEventstore::Commands::Read]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
module RevisionCheck
|
|
6
|
+
# @!visibility private
|
|
7
|
+
class CurrentRevision
|
|
8
|
+
class StreamRevision
|
|
9
|
+
include Extensions::OptionsExtension
|
|
10
|
+
include Extensions::OptionsDefaults
|
|
11
|
+
|
|
12
|
+
# @!attribute revision
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:revision)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class EventTypeRevisions
|
|
18
|
+
include Extensions::OptionsExtension
|
|
19
|
+
include Extensions::OptionsDefaults
|
|
20
|
+
|
|
21
|
+
# @!attribute revisions
|
|
22
|
+
# @return [Array<PgEventstore::EventsGlobalIndex::RevisionCheckRepr>]
|
|
23
|
+
attribute(:revisions)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# @param stream [PgEventstore::Stream]
|
|
28
|
+
# @param stream_revision [Integer]
|
|
29
|
+
# @param expected_revision [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
|
|
30
|
+
# @param index_filtering_queries [PgEventstore::IndexFilteringQueries]
|
|
31
|
+
# @return [CurrentRevision::StreamRevision, CurrentRevision::EventTypeRevisions, nil]
|
|
32
|
+
def build(stream, stream_revision, expected_revision, index_filtering_queries)
|
|
33
|
+
case expected_revision
|
|
34
|
+
in ExpectedRevision::StreamRevision
|
|
35
|
+
StreamRevision.new(revision: stream_revision)
|
|
36
|
+
in ExpectedRevision::EventTypeRevisions
|
|
37
|
+
indexes = index_filtering_queries.fetch_indexes_for_revision_validation(
|
|
38
|
+
stream, expected_revision.revisions
|
|
39
|
+
)
|
|
40
|
+
EventTypeRevisions.new(revisions: indexes)
|
|
41
|
+
in NilClass
|
|
42
|
+
# do nothing
|
|
43
|
+
else
|
|
44
|
+
raise ArgumentError, "Unsupported expected revision #{expected_revision.inspect}."
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
module RevisionCheck
|
|
6
|
+
# @!visibility private
|
|
7
|
+
class EventTypeRevisionsComparison
|
|
8
|
+
class << self
|
|
9
|
+
# @param current_revision [Integer]
|
|
10
|
+
# @param expected_revision [Symbol, Integer]
|
|
11
|
+
# @param expected_markers [Array<String>, nil]
|
|
12
|
+
# @param event_type [String, Symbol]
|
|
13
|
+
# @return [PgEventstore::WrongExpectedTypesRevisionError::Verdict, nil]
|
|
14
|
+
def verdict(current_revision, expected_revision, expected_markers: nil, event_type: :any)
|
|
15
|
+
return if expected_revision == :any
|
|
16
|
+
|
|
17
|
+
verdict_sym =
|
|
18
|
+
case [current_revision, expected_revision]
|
|
19
|
+
in [Event::NON_EXISTING_EVENT_REVISION, Integer]
|
|
20
|
+
:event_is_absent
|
|
21
|
+
in [Integer, Integer]
|
|
22
|
+
:event_revision_does_not_match unless current_revision == expected_revision
|
|
23
|
+
in [Integer, Symbol]
|
|
24
|
+
if current_revision == Event::NON_EXISTING_EVENT_REVISION && expected_revision == :event_exists
|
|
25
|
+
:event_is_absent
|
|
26
|
+
elsif current_revision > Event::NON_EXISTING_EVENT_REVISION && expected_revision == :no_event
|
|
27
|
+
:event_is_present
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
Utils.missing_implementation!([current_revision, expected_revision])
|
|
31
|
+
end
|
|
32
|
+
return unless verdict_sym
|
|
33
|
+
|
|
34
|
+
WrongExpectedTypesRevisionError::Verdict.new(
|
|
35
|
+
verdict: verdict_sym,
|
|
36
|
+
event_type:,
|
|
37
|
+
current_revision:,
|
|
38
|
+
expected_revision:,
|
|
39
|
+
expected_markers:
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
module RevisionCheck
|
|
6
|
+
# @!visibility private
|
|
7
|
+
class ExpectedRevision
|
|
8
|
+
class StreamRevision
|
|
9
|
+
include Extensions::OptionsExtension
|
|
10
|
+
include Extensions::OptionsDefaults
|
|
11
|
+
|
|
12
|
+
# @!attribute revision
|
|
13
|
+
# @return [Symbol, Integer]
|
|
14
|
+
attribute(:revision)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class EventTypeRevision
|
|
18
|
+
include Extensions::OptionsExtension
|
|
19
|
+
include Extensions::OptionsDefaults
|
|
20
|
+
|
|
21
|
+
# @!attribute expected_revision
|
|
22
|
+
# @return [Symbol, Integer]
|
|
23
|
+
attribute(:expected_revision)
|
|
24
|
+
# @!attribute event_type
|
|
25
|
+
# @return [String, nil]
|
|
26
|
+
attribute(:event_type)
|
|
27
|
+
# @!attribute sequence_number
|
|
28
|
+
# @return [Integer]
|
|
29
|
+
attribute(:sequence_number)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class EventTypeRevisionWithMarkers
|
|
33
|
+
include Extensions::OptionsExtension
|
|
34
|
+
include Extensions::OptionsDefaults
|
|
35
|
+
|
|
36
|
+
# @!attribute expected_revision
|
|
37
|
+
# @return [Symbol, Integer]
|
|
38
|
+
attribute(:expected_revision)
|
|
39
|
+
# @!attribute event_type
|
|
40
|
+
# @return [String, nil]
|
|
41
|
+
attribute(:event_type)
|
|
42
|
+
# @!attribute markers
|
|
43
|
+
# @return [Array<String>]
|
|
44
|
+
attribute(:markers)
|
|
45
|
+
# @!attribute sequence_number
|
|
46
|
+
# @return [Integer]
|
|
47
|
+
attribute(:sequence_number)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class MarkersRevision
|
|
51
|
+
include Extensions::OptionsExtension
|
|
52
|
+
include Extensions::OptionsDefaults
|
|
53
|
+
|
|
54
|
+
# @!attribute expected_revision
|
|
55
|
+
# @return [Symbol, Integer]
|
|
56
|
+
attribute(:expected_revision)
|
|
57
|
+
# @!attribute markers
|
|
58
|
+
# @return [Array<String>]
|
|
59
|
+
attribute(:markers)
|
|
60
|
+
# @!attribute sequence_number
|
|
61
|
+
# @return [Integer]
|
|
62
|
+
attribute(:sequence_number)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class EventTypeRevisions
|
|
66
|
+
include Extensions::OptionsExtension
|
|
67
|
+
include Extensions::OptionsDefaults
|
|
68
|
+
|
|
69
|
+
# @!attribute revisions
|
|
70
|
+
# @return [Array<EventTypeRevision, EventTypeRevisionWithMarkers, MarkersRevision>]
|
|
71
|
+
attribute(:revisions)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class << self
|
|
75
|
+
# @param expected_revision [Symbol, Integer, Hash]
|
|
76
|
+
# @return [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
|
|
77
|
+
def build(expected_revision)
|
|
78
|
+
case expected_revision
|
|
79
|
+
in Integer | Symbol
|
|
80
|
+
StreamRevision.new(revision: expected_revision)
|
|
81
|
+
in Hash
|
|
82
|
+
revisions = expected_revision.map.with_index do |(key, value), index|
|
|
83
|
+
case [key, value]
|
|
84
|
+
# { 'Foo' => 1 }, { 'Foo' => :any }, etc
|
|
85
|
+
in [String, Integer | Symbol]
|
|
86
|
+
EventTypeRevision.new(event_type: key, expected_revision: value, sequence_number: index)
|
|
87
|
+
# { 'Foo' => { expected_revision: 1, markers: ['foo'] } },
|
|
88
|
+
# { 'Foo' => { expected_revision: :any, markers: ['foo'] } }, etc
|
|
89
|
+
in [String, Hash]
|
|
90
|
+
markers = extract_markers(value)
|
|
91
|
+
expected_revision = extract_expected_revision(value)
|
|
92
|
+
EventTypeRevisionWithMarkers.new(
|
|
93
|
+
event_type: key, expected_revision:, markers:, sequence_number: index
|
|
94
|
+
)
|
|
95
|
+
# { any: => { expected_revision: 1, markers: ['foo'] } },
|
|
96
|
+
# { any: => { expected_revision: :any, markers: ['foo'] } }, etc
|
|
97
|
+
in [:any, Hash]
|
|
98
|
+
markers = extract_markers(value)
|
|
99
|
+
expected_revision = extract_expected_revision(value)
|
|
100
|
+
MarkersRevision.new(expected_revision:, markers:, sequence_number: index)
|
|
101
|
+
else
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
end.compact
|
|
105
|
+
EventTypeRevisions.new(revisions:)
|
|
106
|
+
in NilClass
|
|
107
|
+
# do nothing
|
|
108
|
+
else
|
|
109
|
+
raise ArgumentError, "Unsupported :expected_revision #{expected_revision.inspect} option."
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
# @param hash [Hash]
|
|
116
|
+
# @return [Symbol, Integer]
|
|
117
|
+
def extract_expected_revision(hash)
|
|
118
|
+
hash in { expected_revision: Symbol | Integer => expected_revision }
|
|
119
|
+
expected_revision ||
|
|
120
|
+
raise(ArgumentError, "Unsupported expected revision #{hash[:expected_revision].inspect} value.")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @param hash [Hash]
|
|
124
|
+
# @return [Array<String>]
|
|
125
|
+
def extract_markers(hash)
|
|
126
|
+
markers = hash[:markers]&.grep(String)
|
|
127
|
+
raise ArgumentError, "Unsupported markers: #{hash[:markers].inspect}." if markers.nil? || markers.empty?
|
|
128
|
+
|
|
129
|
+
markers
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'expected_revision'
|
|
4
|
+
require_relative 'current_revision'
|
|
5
|
+
require_relative 'event_type_revisions_comparison'
|
|
6
|
+
require_relative 'stream_revision_comparison'
|
|
7
|
+
|
|
8
|
+
module PgEventstore
|
|
9
|
+
module Commands
|
|
10
|
+
module RevisionCheck
|
|
11
|
+
# @!visibility private
|
|
12
|
+
class StreamRevisionCheck
|
|
13
|
+
class << self
|
|
14
|
+
# @param current_revision [CurrentRevision::StreamRevision, CurrentRevision::EventTypeRevisions, nil]
|
|
15
|
+
# @param expected_revision [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
|
|
16
|
+
# @param stream [PgEventstore::Stream]
|
|
17
|
+
# @return [void]
|
|
18
|
+
def assert_eq!(current_revision, expected_revision, stream)
|
|
19
|
+
case [current_revision, expected_revision]
|
|
20
|
+
in [_, NilClass]
|
|
21
|
+
# do nothing. We don't have expected revision
|
|
22
|
+
in [CurrentRevision::StreamRevision, ExpectedRevision::StreamRevision]
|
|
23
|
+
verdict = StreamRevisionComparison.verdict(current_revision.revision, expected_revision.revision)
|
|
24
|
+
if verdict
|
|
25
|
+
raise WrongExpectedRevisionError.new(
|
|
26
|
+
revision: current_revision.revision,
|
|
27
|
+
expected_revision: expected_revision.revision,
|
|
28
|
+
stream:,
|
|
29
|
+
verdict:
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
in [CurrentRevision::EventTypeRevisions, ExpectedRevision::EventTypeRevisions]
|
|
33
|
+
verdicts = []
|
|
34
|
+
rev_check_indexes = current_revision.revisions.to_h { [_1.sequence_number, _1] }
|
|
35
|
+
expected_revision.revisions.each do |revision|
|
|
36
|
+
index = find_index(revision, rev_check_indexes)
|
|
37
|
+
verdict =
|
|
38
|
+
case revision
|
|
39
|
+
when ExpectedRevision::EventTypeRevision
|
|
40
|
+
EventTypeRevisionsComparison.verdict(
|
|
41
|
+
index.stream_revision,
|
|
42
|
+
revision.expected_revision,
|
|
43
|
+
event_type: revision.event_type
|
|
44
|
+
)
|
|
45
|
+
when ExpectedRevision::EventTypeRevisionWithMarkers
|
|
46
|
+
EventTypeRevisionsComparison.verdict(
|
|
47
|
+
index.stream_revision,
|
|
48
|
+
revision.expected_revision,
|
|
49
|
+
expected_markers: revision.markers,
|
|
50
|
+
event_type: revision.event_type
|
|
51
|
+
)
|
|
52
|
+
when ExpectedRevision::MarkersRevision
|
|
53
|
+
EventTypeRevisionsComparison.verdict(
|
|
54
|
+
index.stream_revision,
|
|
55
|
+
revision.expected_revision,
|
|
56
|
+
expected_markers: revision.markers
|
|
57
|
+
)
|
|
58
|
+
else
|
|
59
|
+
Utils.missing_implementation!(revision)
|
|
60
|
+
end
|
|
61
|
+
verdicts.push(verdict) if verdict
|
|
62
|
+
end
|
|
63
|
+
raise WrongExpectedTypesRevisionError.new(stream:, verdicts:) if verdicts.any?
|
|
64
|
+
else
|
|
65
|
+
Utils.missing_implementation!([current_revision, expected_revision])
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
# @param expected_revision [ExpectedRevision::EventTypeRevision,
|
|
72
|
+
# ExpectedRevision::EventTypeRevisionWithMarkers, ExpectedRevision::MarkersRevision]
|
|
73
|
+
# @param rev_check_indexes [Hash<Integer, PgEventstore::EventGlobalIndex::RevisionCheckRepr>]
|
|
74
|
+
# @return [PgEventstore::EventGlobalIndex::RevisionCheckRepr]
|
|
75
|
+
def find_index(expected_revision, rev_check_indexes)
|
|
76
|
+
from_dictionary = rev_check_indexes[expected_revision.sequence_number]
|
|
77
|
+
return from_dictionary if from_dictionary
|
|
78
|
+
|
|
79
|
+
case expected_revision
|
|
80
|
+
when ExpectedRevision::EventTypeRevision
|
|
81
|
+
EventGlobalIndex::RevisionCheckRepr.new(
|
|
82
|
+
sequence_number: expected_revision.sequence_number, stream_revision: Event::NON_EXISTING_EVENT_REVISION
|
|
83
|
+
)
|
|
84
|
+
when ExpectedRevision::EventTypeRevisionWithMarkers, ExpectedRevision::MarkersRevision
|
|
85
|
+
EventGlobalIndex::RevisionCheckRepr.new(
|
|
86
|
+
sequence_number: expected_revision.sequence_number,
|
|
87
|
+
stream_revision: Event::NON_EXISTING_EVENT_REVISION,
|
|
88
|
+
marker: Event::SYSTEM_SYMBOL
|
|
89
|
+
)
|
|
90
|
+
else
|
|
91
|
+
Utils.missing_implementation!(expected_revision)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
module RevisionCheck
|
|
6
|
+
# @!visibility private
|
|
7
|
+
class StreamRevisionComparison
|
|
8
|
+
class << self
|
|
9
|
+
# @param current_revision [Integer]
|
|
10
|
+
# @param expected_revision [Integer, Symbol]
|
|
11
|
+
# @return [Symbol]
|
|
12
|
+
def verdict(current_revision, expected_revision)
|
|
13
|
+
return if expected_revision == :any
|
|
14
|
+
|
|
15
|
+
case [current_revision, expected_revision]
|
|
16
|
+
in [Stream::NON_EXISTING_STREAM_REVISION, Integer]
|
|
17
|
+
:expected_to_have_stream_with_given_revision
|
|
18
|
+
in [Integer, Integer]
|
|
19
|
+
:unmatched_stream_revision unless current_revision == expected_revision
|
|
20
|
+
in [Integer, Symbol]
|
|
21
|
+
if current_revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :stream_exists
|
|
22
|
+
return :expected_to_have_stream
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if current_revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
|
|
26
|
+
:expected_not_to_have_stream
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
raise ArgumentError
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Commands
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class StreamRevision < AbstractCommand
|
|
7
|
+
# @param stream [PgEventstore::Stream]
|
|
8
|
+
# @return [Integer]
|
|
9
|
+
def call(stream)
|
|
10
|
+
queries.streams_global_index.stream_revision(stream) || Stream::NON_EXISTING_STREAM_REVISION
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -5,14 +5,14 @@ module PgEventstore
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
class SystemStreamReadPaginated < AbstractCommand
|
|
7
7
|
# @see PgEventstore::Commands::Read for docs
|
|
8
|
-
def call(stream, options: {})
|
|
8
|
+
def call(stream, deserializer:, options: {})
|
|
9
9
|
Enumerator.new do |yielder|
|
|
10
10
|
next_position = nil
|
|
11
11
|
loop do
|
|
12
12
|
options = options.merge(from_position: next_position) if next_position
|
|
13
|
-
events = read_cmd.call(stream, options:)
|
|
13
|
+
events = read_cmd.call(stream, deserializer:, options:)
|
|
14
14
|
yielder << events if events.any?
|
|
15
|
-
if end_reached?(events, options[:max_count] || QueryBuilders::
|
|
15
|
+
if end_reached?(events, options[:max_count] || QueryBuilders::EventsGlobalIndexFiltering::DEFAULT_LIMIT)
|
|
16
16
|
raise StopIteration
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ module PgEventstore
|
|
|
43
43
|
# @param direction [String, Symbol, nil]
|
|
44
44
|
# @return [Boolean]
|
|
45
45
|
def forwards?(direction)
|
|
46
|
-
QueryBuilders::
|
|
46
|
+
QueryBuilders::BasicFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::BasicFiltering::SQL_DIRECTIONS[:asc]
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# @return [PgEventstore::Commands::Read]
|
|
@@ -5,11 +5,13 @@ require_relative 'commands/event_modifiers/prepare_link_event'
|
|
|
5
5
|
require_relative 'commands/event_modifiers/prepare_regular_event'
|
|
6
6
|
require_relative 'commands/append'
|
|
7
7
|
require_relative 'commands/read'
|
|
8
|
-
require_relative 'commands/
|
|
9
|
-
require_relative 'commands/
|
|
8
|
+
require_relative 'commands/read_grouped'
|
|
9
|
+
require_relative 'commands/read_streams'
|
|
10
|
+
require_relative 'commands/read_streams_paginated'
|
|
10
11
|
require_relative 'commands/regular_stream_read_paginated'
|
|
11
12
|
require_relative 'commands/system_stream_read_paginated'
|
|
12
13
|
require_relative 'commands/multiple'
|
|
13
14
|
require_relative 'commands/link_to'
|
|
14
15
|
require_relative 'commands/delete_stream'
|
|
15
16
|
require_relative 'commands/delete_event'
|
|
17
|
+
require_relative 'commands/stream_revision'
|
data/lib/pg_eventstore/config.rb
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PgEventstore
|
|
4
|
-
class Config
|
|
5
|
-
|
|
4
|
+
class Config < BasicConfig
|
|
5
|
+
module NodeRole
|
|
6
|
+
# @return [Symbol]
|
|
7
|
+
STANDALONE = :standalone
|
|
8
|
+
# @return [Symbol]
|
|
9
|
+
PRIMARY = :primary
|
|
10
|
+
# @return [Symbol]
|
|
11
|
+
REPLICA = :replica
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
class << self
|
|
14
|
+
# @return [Array<Symbol>]
|
|
15
|
+
def writable
|
|
16
|
+
[STANDALONE, PRIMARY]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array<Symbol>]
|
|
20
|
+
def maintainable
|
|
21
|
+
[STANDALONE]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
8
25
|
|
|
9
26
|
# @!attribute pg_uri
|
|
10
27
|
# @return [String] PostgreSQL connection URI docs
|
|
@@ -55,16 +72,20 @@ module PgEventstore
|
|
|
55
72
|
# @!attribute subscription_graceful_shutdown_timeout
|
|
56
73
|
# @return [Integer] the number of seconds to wait until force-shutdown the subscription during the stop process
|
|
57
74
|
option(:subscription_graceful_shutdown_timeout) { 15 }
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
# @!attribute events_subscription_position_update_interval
|
|
76
|
+
# @return [Float, Integer] events subscription position update interval
|
|
77
|
+
option(:events_subscription_position_update_interval) { 0.2 }
|
|
78
|
+
# @!attribute eventstore_role
|
|
79
|
+
# @return [Symbol] the role of this node
|
|
80
|
+
option(:eventstore_role) { NodeRole::STANDALONE }
|
|
81
|
+
# @!attribute max_events_to_replicate
|
|
82
|
+
# @return [Integer] max number of events to replicate at a time
|
|
83
|
+
option(:max_events_to_replicate) { 10_000 }
|
|
64
84
|
|
|
65
85
|
# Computes a value for usage in PgEventstore::Connection
|
|
66
86
|
# @return [Hash]
|
|
67
87
|
def connection_options
|
|
88
|
+
puts "DEPRECATED: Config##{__method__} will be removed in next major version with no replacement"
|
|
68
89
|
{ uri: pg_uri, pool_size: connection_pool_size, pool_timeout: connection_pool_timeout }
|
|
69
90
|
end
|
|
70
91
|
end
|
|
@@ -31,17 +31,22 @@ module PgEventstore
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# A shorthand from ConnectionPool#with.
|
|
34
|
-
# @yieldparam connection [
|
|
34
|
+
# @yieldparam connection [PgEventstore::PgConnection] PostgreSQL connection instance
|
|
35
35
|
# @return [Object] a value of a given block
|
|
36
36
|
def with(&)
|
|
37
37
|
should_retry = true
|
|
38
38
|
@pool.with do |conn|
|
|
39
39
|
yield conn
|
|
40
40
|
rescue PG::ConnectionBad, PG::UnableToSend
|
|
41
|
+
unless should_retry
|
|
42
|
+
# Connection is broken. We should throw it away
|
|
43
|
+
@pool.discard_current_connection
|
|
44
|
+
raise
|
|
45
|
+
end
|
|
46
|
+
|
|
41
47
|
# Recover a connection after fork or when we lost a connection to PostgreSQL. We retry only once and without any
|
|
42
48
|
# delay.
|
|
43
49
|
conn.sync_reset
|
|
44
|
-
raise unless should_retry
|
|
45
50
|
|
|
46
51
|
should_retry = false
|
|
47
52
|
retry
|
|
@@ -53,6 +58,20 @@ module PgEventstore
|
|
|
53
58
|
@pool.shutdown(&:close)
|
|
54
59
|
end
|
|
55
60
|
|
|
61
|
+
# Restore connection after shutdown by re-initializing connection pool
|
|
62
|
+
# @return [void]
|
|
63
|
+
def establish_connection
|
|
64
|
+
@pool = nil
|
|
65
|
+
init_pool
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [void]
|
|
69
|
+
def discard_current_connection
|
|
70
|
+
@pool.discard_current_connection do |conn|
|
|
71
|
+
conn.close unless conn.finished?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
56
75
|
private
|
|
57
76
|
|
|
58
77
|
# @return [ConnectionPool]
|