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/errors.rb
CHANGED
|
@@ -55,14 +55,19 @@ module PgEventstore
|
|
|
55
55
|
# @!attribute expected_revision
|
|
56
56
|
# @return [Integer, Symbol]
|
|
57
57
|
attr_reader :expected_revision
|
|
58
|
+
# @!attribute verdict
|
|
59
|
+
# @return [Symbol]
|
|
60
|
+
attr_reader :verdict
|
|
58
61
|
|
|
59
62
|
# @param revision [Integer]
|
|
60
63
|
# @param expected_revision [Integer, Symbol]
|
|
61
64
|
# @param stream [PgEventstore::Stream]
|
|
62
|
-
|
|
65
|
+
# @param verdict [Symbol]
|
|
66
|
+
def initialize(revision:, expected_revision:, stream:, verdict:)
|
|
63
67
|
@revision = revision
|
|
64
68
|
@expected_revision = expected_revision
|
|
65
69
|
@stream = stream
|
|
70
|
+
@verdict = verdict
|
|
66
71
|
super(user_friendly_message)
|
|
67
72
|
end
|
|
68
73
|
|
|
@@ -70,13 +75,18 @@ module PgEventstore
|
|
|
70
75
|
|
|
71
76
|
# @return [String]
|
|
72
77
|
def user_friendly_message
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
case verdict
|
|
79
|
+
when :expected_to_have_stream_with_given_revision
|
|
80
|
+
current_no_stream
|
|
81
|
+
when :unmatched_stream_revision
|
|
82
|
+
unmatched_stream_revision
|
|
83
|
+
when :expected_to_have_stream
|
|
84
|
+
expected_stream_exists
|
|
85
|
+
when :expected_not_to_have_stream
|
|
86
|
+
expected_no_stream
|
|
87
|
+
else
|
|
88
|
+
Utils.missing_implementation!(verdict)
|
|
75
89
|
end
|
|
76
|
-
return expected_no_stream if revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
|
|
77
|
-
return current_no_stream if revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision.is_a?(Integer)
|
|
78
|
-
|
|
79
|
-
unmatched_stream_revision
|
|
80
90
|
end
|
|
81
91
|
|
|
82
92
|
# @return [String]
|
|
@@ -108,16 +118,129 @@ module PgEventstore
|
|
|
108
118
|
end
|
|
109
119
|
end
|
|
110
120
|
|
|
121
|
+
class WrongExpectedTypesRevisionError < Error
|
|
122
|
+
class Verdict
|
|
123
|
+
include Extensions::OptionsExtension
|
|
124
|
+
include Extensions::OptionsDefaults
|
|
125
|
+
|
|
126
|
+
# @!attribute verdict
|
|
127
|
+
# @return [Symbol]
|
|
128
|
+
attribute(:verdict)
|
|
129
|
+
# @!attribute event_type
|
|
130
|
+
# @return [String, Symbol]
|
|
131
|
+
attribute(:event_type)
|
|
132
|
+
# @!attribute current_revision
|
|
133
|
+
# @return [Integer]
|
|
134
|
+
attribute(:current_revision)
|
|
135
|
+
# @!attribute expected_revision
|
|
136
|
+
# @return [Integer, Symbol]
|
|
137
|
+
attribute(:expected_revision)
|
|
138
|
+
# @!attribute expected_markers
|
|
139
|
+
# @return [Array<String>, nil]
|
|
140
|
+
attribute(:expected_markers)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @!attribute stream
|
|
144
|
+
# @return [PgEventstore::Stream]
|
|
145
|
+
attr_reader :stream
|
|
146
|
+
# @!attribute verdicts
|
|
147
|
+
# @return [Array<PgEventstore::WrongExpectedTypesRevisionError::Verdict>]
|
|
148
|
+
attr_reader :verdicts
|
|
149
|
+
|
|
150
|
+
# @param stream [PgEventstore::Stream]
|
|
151
|
+
# @param verdicts [Array<PgEventstore::WrongExpectedTypesRevisionError::Verdict>]
|
|
152
|
+
def initialize(stream:, verdicts:)
|
|
153
|
+
@stream = stream
|
|
154
|
+
@verdicts = verdicts
|
|
155
|
+
super(user_friendly_message)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
# @return [String]
|
|
161
|
+
def user_friendly_message
|
|
162
|
+
messages =
|
|
163
|
+
verdicts.map do |verdict|
|
|
164
|
+
case verdict.verdict
|
|
165
|
+
when :event_is_absent
|
|
166
|
+
event_is_absent(verdict)
|
|
167
|
+
when :event_revision_does_not_match
|
|
168
|
+
event_revision_does_not_match(verdict)
|
|
169
|
+
when :event_is_present
|
|
170
|
+
event_is_present(verdict)
|
|
171
|
+
else
|
|
172
|
+
Utils.missing_implementation!(verdict.verdict)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
messages.join('; ')
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
179
|
+
# @return [String]
|
|
180
|
+
def event_is_absent(verdict)
|
|
181
|
+
<<~TEXT.strip
|
|
182
|
+
Expected #{stream_descr} stream to contain #{event_descr(verdict)} with #{revision_descr(verdict)}, \
|
|
183
|
+
but this event does not exist.
|
|
184
|
+
TEXT
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
188
|
+
# @return [String]
|
|
189
|
+
def event_is_present(verdict)
|
|
190
|
+
"Expected #{stream_descr} stream not to contain #{event_descr(verdict)}, but it actually exists."
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
194
|
+
# @return [String]
|
|
195
|
+
def event_revision_does_not_match(verdict)
|
|
196
|
+
<<~TEXT.strip
|
|
197
|
+
Expected #{stream_descr} stream to contain #{event_descr(verdict)} with #{revision_descr(verdict)}, \
|
|
198
|
+
but it actually has #{verdict.current_revision} revision.
|
|
199
|
+
TEXT
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# @return [String]
|
|
203
|
+
def stream_descr
|
|
204
|
+
stream.to_hash.inspect
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
208
|
+
# @return [String]
|
|
209
|
+
def event_descr(verdict)
|
|
210
|
+
if verdict.event_type == :any
|
|
211
|
+
markers = verdict.expected_markers.map(&:inspect).join(', ')
|
|
212
|
+
"any event with some of #{markers} marker(s)"
|
|
213
|
+
elsif verdict.expected_markers
|
|
214
|
+
markers = verdict.expected_markers.map(&:inspect).join(', ')
|
|
215
|
+
"#{verdict.event_type.inspect} event with some of #{markers} marker(s)"
|
|
216
|
+
else
|
|
217
|
+
"#{verdict.event_type.inspect} event"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
222
|
+
# @return [String]
|
|
223
|
+
def revision_descr(verdict)
|
|
224
|
+
if verdict.expected_revision.is_a?(Integer)
|
|
225
|
+
"#{verdict.expected_revision} revision"
|
|
226
|
+
elsif verdict.expected_revision == :event_exists
|
|
227
|
+
'some revision'
|
|
228
|
+
else
|
|
229
|
+
"#{verdict.expected_revision.inspect} revision"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
111
234
|
class RecordNotFound < Error
|
|
112
235
|
# @!attribute table_name
|
|
113
236
|
# @return [String]
|
|
114
237
|
attr_reader :table_name
|
|
115
238
|
# @!attribute id
|
|
116
|
-
# @return [
|
|
239
|
+
# @return [Object]
|
|
117
240
|
attr_reader :id
|
|
118
241
|
|
|
119
242
|
# @param table_name [String]
|
|
120
|
-
# @param id [
|
|
243
|
+
# @param id [Object]
|
|
121
244
|
def initialize(table_name, id)
|
|
122
245
|
@table_name = table_name
|
|
123
246
|
@id = id
|
|
@@ -126,7 +249,7 @@ module PgEventstore
|
|
|
126
249
|
|
|
127
250
|
# @return [String]
|
|
128
251
|
def user_friendly_message
|
|
129
|
-
"Could not find/update #{table_name.inspect} record
|
|
252
|
+
"Could not find/update/delete #{table_name.inspect} record by #{@id.inspect}."
|
|
130
253
|
end
|
|
131
254
|
end
|
|
132
255
|
|
|
@@ -255,4 +378,7 @@ module PgEventstore
|
|
|
255
378
|
super()
|
|
256
379
|
end
|
|
257
380
|
end
|
|
381
|
+
|
|
382
|
+
class NotSupportedError < Error
|
|
383
|
+
end
|
|
258
384
|
end
|
data/lib/pg_eventstore/event.rb
CHANGED
|
@@ -7,11 +7,17 @@ module PgEventstore
|
|
|
7
7
|
# @return [String] a type of link event
|
|
8
8
|
LINK_TYPE = '$>'
|
|
9
9
|
# @return [String]
|
|
10
|
+
SYSTEM_SYMBOL = "\u2592"
|
|
11
|
+
# @return [String]
|
|
12
|
+
MARKERS_METADATA_KEY = "#{SYSTEM_SYMBOL}m".freeze
|
|
13
|
+
# @return [String]
|
|
10
14
|
PRIMARY_TABLE_NAME = 'events'
|
|
15
|
+
# @return [Integer]
|
|
16
|
+
NON_EXISTING_EVENT_REVISION = -1
|
|
11
17
|
|
|
12
18
|
# @!attribute id
|
|
13
|
-
# @return [String]
|
|
14
|
-
attribute(:id)
|
|
19
|
+
# @return [String] UUIDv7
|
|
20
|
+
attribute(:id) { SecureRandom.uuid_v7 }
|
|
15
21
|
# @!attribute type
|
|
16
22
|
# @return [String] event type
|
|
17
23
|
attribute(:type) { self.class.name }
|
|
@@ -27,6 +33,12 @@ module PgEventstore
|
|
|
27
33
|
# @!attribute data
|
|
28
34
|
# @return [Hash] event's data
|
|
29
35
|
attribute(:data) { {} }
|
|
36
|
+
# @!attribute markers
|
|
37
|
+
# @return [Array<String>] event markers
|
|
38
|
+
attribute(:markers) { [] }
|
|
39
|
+
# @!attribute feature_markers
|
|
40
|
+
# @return [Array<FeatureMarker>] feature-specific markers that can't be put under #markers
|
|
41
|
+
attribute(:feature_markers) { [] }
|
|
30
42
|
# @!attribute metadata
|
|
31
43
|
# @return [Hash] event's metadata
|
|
32
44
|
attribute(:metadata) { {} }
|
|
@@ -45,6 +57,15 @@ module PgEventstore
|
|
|
45
57
|
# @!attribute created_at
|
|
46
58
|
# @return [Time, nil] a timestamp an event was created at
|
|
47
59
|
attribute(:created_at)
|
|
60
|
+
# @!attribute caused_by
|
|
61
|
+
# @return [PgEventstore::Event, nil]
|
|
62
|
+
attribute(:caused_by)
|
|
63
|
+
# @!attribute correlation_id
|
|
64
|
+
# @return [String, nil] UUIDv7
|
|
65
|
+
attribute(:correlation_id)
|
|
66
|
+
# @!attribute causation_id
|
|
67
|
+
# @return [String, nil] UUIDv7
|
|
68
|
+
attribute(:causation_id)
|
|
48
69
|
|
|
49
70
|
# Implements comparison of `PgEventstore::Event`-s. Two events matches if all of their attributes matches
|
|
50
71
|
# @param other [Object, PgEventstore::Event]
|
|
@@ -54,6 +75,7 @@ module PgEventstore
|
|
|
54
75
|
|
|
55
76
|
attributes_hash.except(:link) == other.attributes_hash.except(:link)
|
|
56
77
|
end
|
|
78
|
+
alias eql? ==
|
|
57
79
|
|
|
58
80
|
# Detect whether an event is a link event
|
|
59
81
|
# @return [Boolean]
|
|
@@ -61,10 +83,20 @@ module PgEventstore
|
|
|
61
83
|
!link_global_position.nil?
|
|
62
84
|
end
|
|
63
85
|
|
|
86
|
+
# @return [Integer]
|
|
87
|
+
def hash
|
|
88
|
+
attributes_hash.except(:link).hash
|
|
89
|
+
end
|
|
90
|
+
|
|
64
91
|
# Detect whether an event is a system event
|
|
65
92
|
# @return [Boolean]
|
|
66
93
|
def system?
|
|
67
94
|
type.start_with?('$')
|
|
68
95
|
end
|
|
96
|
+
|
|
97
|
+
# @return [self]
|
|
98
|
+
def dup
|
|
99
|
+
self.class.new(**Utils.deep_dup(options_hash))
|
|
100
|
+
end
|
|
69
101
|
end
|
|
70
102
|
end
|
|
@@ -4,20 +4,20 @@ module PgEventstore
|
|
|
4
4
|
# @!visibility private
|
|
5
5
|
class EventDeserializer
|
|
6
6
|
# @!attribute middlewares
|
|
7
|
-
# @return [Array
|
|
7
|
+
# @return [Array<Middleware>]
|
|
8
8
|
attr_reader :middlewares
|
|
9
9
|
# @!attribute event_class_resolver
|
|
10
10
|
# @return [#call]
|
|
11
11
|
attr_reader :event_class_resolver
|
|
12
12
|
|
|
13
|
-
# @param middlewares [Array<
|
|
13
|
+
# @param middlewares [Array<Middleware>]
|
|
14
14
|
# @param event_class_resolver [#call]
|
|
15
15
|
def initialize(middlewares, event_class_resolver)
|
|
16
16
|
@middlewares = middlewares
|
|
17
17
|
@event_class_resolver = event_class_resolver
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# @param raw_events [Array<Hash>]
|
|
20
|
+
# @param raw_events [Array<Hash>, Enumerator<Hash>]
|
|
21
21
|
# @return [Array<PgEventstore::Event>]
|
|
22
22
|
def deserialize_many(raw_events)
|
|
23
23
|
raw_events.map(&method(:deserialize))
|
|
@@ -33,7 +33,8 @@ module PgEventstore
|
|
|
33
33
|
event.stream = PgEventstore::Stream.new(
|
|
34
34
|
**attrs.slice('context', 'stream_name', 'stream_id').transform_keys(&:to_sym)
|
|
35
35
|
)
|
|
36
|
-
event.link =
|
|
36
|
+
event.link = deserialize(attrs['link']) if attrs.key?('link')
|
|
37
|
+
event.markers = event.metadata[Event::MARKERS_METADATA_KEY] || []
|
|
37
38
|
event
|
|
38
39
|
end
|
|
39
40
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventGlobalIndex
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute global_position
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:global_position)
|
|
12
|
+
# @!attribute stream_revision
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:stream_revision)
|
|
15
|
+
# @!attribute context_partition_id
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
attribute(:context_partition_id)
|
|
18
|
+
# @!attribute stream_name_partition_id
|
|
19
|
+
# @return [Integer]
|
|
20
|
+
attribute(:stream_name_partition_id)
|
|
21
|
+
# @!attribute event_type_partition_id
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attribute(:event_type_partition_id)
|
|
24
|
+
# @!attribute streams_global_index_id
|
|
25
|
+
# @return [Integer]
|
|
26
|
+
attribute(:streams_global_index_id)
|
|
27
|
+
|
|
28
|
+
# EventGlobalIndex representation that is used in subscriptions
|
|
29
|
+
class SubscriptionRepr
|
|
30
|
+
include Extensions::OptionsExtension
|
|
31
|
+
include Extensions::OptionsDefaults
|
|
32
|
+
|
|
33
|
+
# @!attribute global_position
|
|
34
|
+
# @return [Integer]
|
|
35
|
+
attribute(:global_position)
|
|
36
|
+
# @!attribute subscription_position
|
|
37
|
+
# @return [Integer]
|
|
38
|
+
attribute(:subscription_position)
|
|
39
|
+
# @!attribute event_type_partition_id
|
|
40
|
+
# @return [Integer]
|
|
41
|
+
attribute(:event_type_partition_id)
|
|
42
|
+
|
|
43
|
+
# @return [Hash]
|
|
44
|
+
def to_subscription_position_attrs
|
|
45
|
+
{ global_position:, subscription_position: }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# EventGlobalIndex representation that is used in Read API
|
|
50
|
+
class ReadApiRepr
|
|
51
|
+
include Extensions::OptionsExtension
|
|
52
|
+
include Extensions::OptionsDefaults
|
|
53
|
+
|
|
54
|
+
# @!attribute global_position
|
|
55
|
+
# @return [Integer]
|
|
56
|
+
attribute(:global_position)
|
|
57
|
+
# @!attribute event_type_partition_id
|
|
58
|
+
# @return [Integer]
|
|
59
|
+
attribute(:event_type_partition_id)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# EventGlobalIndex representation that is used in Write API
|
|
63
|
+
class WriteApiRepr
|
|
64
|
+
include Extensions::OptionsExtension
|
|
65
|
+
include Extensions::OptionsDefaults
|
|
66
|
+
|
|
67
|
+
# @!attribute global_position
|
|
68
|
+
# @return [Integer]
|
|
69
|
+
attribute(:global_position)
|
|
70
|
+
# @!attribute event_type_partition_id
|
|
71
|
+
# @return [Integer]
|
|
72
|
+
attribute(:event_type_partition_id)
|
|
73
|
+
# @!attribute stream_revision
|
|
74
|
+
# @return [Integer]
|
|
75
|
+
attribute(:stream_revision)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# EventGlobalIndex representation for revision validation in #append_to_stream
|
|
79
|
+
class RevisionCheckRepr
|
|
80
|
+
include Extensions::OptionsExtension
|
|
81
|
+
include Extensions::OptionsDefaults
|
|
82
|
+
|
|
83
|
+
# @!attribute stream_revision
|
|
84
|
+
# @return [Integer]
|
|
85
|
+
attribute(:stream_revision)
|
|
86
|
+
# @!attribute sequence_number
|
|
87
|
+
# @return [Integer]
|
|
88
|
+
attribute(:sequence_number)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
module ReprType
|
|
92
|
+
SUBSCRIPTION = :subscription
|
|
93
|
+
READ_API = :read_api
|
|
94
|
+
WRITE_API = :write_api
|
|
95
|
+
REVISION_CHECK = :revision_check
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class << self
|
|
99
|
+
# @param attributes [Hash<Symbol, Object>]
|
|
100
|
+
# @param repr [Symbol, nil]
|
|
101
|
+
# @return [EventGlobalIndex, SubscriptionRepr, ReadApiRepr, WriteApiRepr, RevisionCheckRepr]
|
|
102
|
+
def create_representation(attributes, repr: nil)
|
|
103
|
+
case repr
|
|
104
|
+
when ReprType::SUBSCRIPTION
|
|
105
|
+
SubscriptionRepr.new(**attributes)
|
|
106
|
+
when ReprType::READ_API
|
|
107
|
+
ReadApiRepr.new(**attributes)
|
|
108
|
+
when ReprType::WRITE_API
|
|
109
|
+
WriteApiRepr.new(**attributes)
|
|
110
|
+
when ReprType::REVISION_CHECK
|
|
111
|
+
RevisionCheckRepr.new(**attributes)
|
|
112
|
+
else
|
|
113
|
+
new(**attributes)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventMarker
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute id
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:id)
|
|
12
|
+
# @!attribute name
|
|
13
|
+
# @return [String]
|
|
14
|
+
attribute(:name)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventMarkerIndex
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute marker_id
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:marker_id)
|
|
12
|
+
# @!attribute streams_global_index_id
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:streams_global_index_id)
|
|
15
|
+
# @!attribute event_type_partition_id
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
attribute(:event_type_partition_id)
|
|
18
|
+
# @!attribute global_position
|
|
19
|
+
# @return [Integer]
|
|
20
|
+
attribute(:global_position)
|
|
21
|
+
# @!attribute stream_revision
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attribute(:stream_revision)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -18,6 +18,12 @@ module PgEventstore
|
|
|
18
18
|
@middlewares.each do |middleware|
|
|
19
19
|
middleware.serialize(event)
|
|
20
20
|
end
|
|
21
|
+
event.markers.uniq!
|
|
22
|
+
if event.markers.any?
|
|
23
|
+
event.metadata[Event::MARKERS_METADATA_KEY] = event.markers
|
|
24
|
+
else
|
|
25
|
+
event.metadata.delete(Event::MARKERS_METADATA_KEY)
|
|
26
|
+
end
|
|
21
27
|
event
|
|
22
28
|
end
|
|
23
29
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Extensions
|
|
5
|
+
module ActsAsConfigurable
|
|
6
|
+
# @param config_class [Class<PgEventstore:::BasicConfig>]
|
|
7
|
+
# @param default_config [Symbol]
|
|
8
|
+
# @return [void]
|
|
9
|
+
def acts_as_configurable(config_class:, default_config: :default)
|
|
10
|
+
const_set(:DEFAULT_CONFIG, default_config)
|
|
11
|
+
const_set(:CONFIG_CLASS, config_class)
|
|
12
|
+
extend Configurable
|
|
13
|
+
init_variables
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module Configurable
|
|
17
|
+
# @!attribute mutex
|
|
18
|
+
# @return [Thread::Mutex]
|
|
19
|
+
attr_reader :mutex
|
|
20
|
+
private :mutex
|
|
21
|
+
|
|
22
|
+
# Creates a Config if not exists and yields it to the given block.
|
|
23
|
+
# @param name [Symbol] a name to assign to a config
|
|
24
|
+
# @return [Object] a result of the given block
|
|
25
|
+
def configure(name: const_get(:DEFAULT_CONFIG))
|
|
26
|
+
config_class = const_get(:CONFIG_CLASS)
|
|
27
|
+
mutex.synchronize do
|
|
28
|
+
@config[name] = @config[name] ? config_class.new(name:, **@config[name].options_hash) : config_class.new(name:)
|
|
29
|
+
connection_config_was = connection_options(@config[name])
|
|
30
|
+
|
|
31
|
+
yield(@config[name]).tap do
|
|
32
|
+
@config[name].freeze
|
|
33
|
+
next if connection_config_was == connection_options(@config[name])
|
|
34
|
+
|
|
35
|
+
# Reset the connection if user decided to reconfigure connection's options
|
|
36
|
+
@connection.delete(name)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Array<Symbol>]
|
|
42
|
+
def available_configs
|
|
43
|
+
@config.keys
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @param name [Symbol]
|
|
47
|
+
# @return [PgEventstore::Config]
|
|
48
|
+
def config(name = const_get(:DEFAULT_CONFIG))
|
|
49
|
+
return @config[name] if @config[name]
|
|
50
|
+
|
|
51
|
+
error_message = <<~TEXT
|
|
52
|
+
Could not find #{name.inspect} config. You can define it like this:
|
|
53
|
+
#{self}.configure(name: #{name.inspect}) do |config|
|
|
54
|
+
# your config goes here
|
|
55
|
+
end
|
|
56
|
+
TEXT
|
|
57
|
+
raise error_message
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Look ups and returns a Connection, based on the given config. If not exists - it creates one. This operation
|
|
61
|
+
# is a thread-safe
|
|
62
|
+
# @param name [Symbol]
|
|
63
|
+
# @return [PgEventstore::Connection]
|
|
64
|
+
def connection(name = const_get(:DEFAULT_CONFIG))
|
|
65
|
+
mutex.synchronize do
|
|
66
|
+
@connection[name] ||= Connection.new(**connection_options(config(name)))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# @param config [PgEventstore::Extensions::OptionsExtension]
|
|
73
|
+
# @return [Hash] { uri: String, pool_size: Integer, pool_timeout: Integer }
|
|
74
|
+
def connection_options(config)
|
|
75
|
+
raise NotImplementedError
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [void]
|
|
79
|
+
def init_variables
|
|
80
|
+
default_config = const_get(:DEFAULT_CONFIG)
|
|
81
|
+
@config = { default_config => const_get(:CONFIG_CLASS).new(name: default_config) }
|
|
82
|
+
@connection = {}
|
|
83
|
+
@mutex = Thread::Mutex.new
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Extensions
|
|
5
|
+
# @!visibility private
|
|
6
|
+
module OptionsDefaults
|
|
7
|
+
def ==(other)
|
|
8
|
+
return false unless other.is_a?(self.class)
|
|
9
|
+
|
|
10
|
+
attributes_hash == other.attributes_hash
|
|
11
|
+
end
|
|
12
|
+
alias eql? ==
|
|
13
|
+
|
|
14
|
+
# @return [Integer]
|
|
15
|
+
def hash
|
|
16
|
+
attributes_hash.hash
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [self]
|
|
20
|
+
def dup
|
|
21
|
+
self.class.new(**Utils.deep_dup(options_hash))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -173,8 +173,8 @@ module PgEventstore
|
|
|
173
173
|
# value
|
|
174
174
|
# @return [Hash]
|
|
175
175
|
def options_hash
|
|
176
|
-
self.class.options.
|
|
177
|
-
|
|
176
|
+
self.class.options.to_h do |option|
|
|
177
|
+
[option.name, public_send(option.name)]
|
|
178
178
|
end
|
|
179
179
|
end
|
|
180
180
|
alias attributes_hash options_hash
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
class FeatureMarker
|
|
5
|
+
include Extensions::OptionsExtension
|
|
6
|
+
include Extensions::OptionsDefaults
|
|
7
|
+
|
|
8
|
+
# @!attribute marker
|
|
9
|
+
# @return [String]
|
|
10
|
+
attribute(:marker)
|
|
11
|
+
# @!attribute description
|
|
12
|
+
# @return [String, nil] the description of the maker. Can be used as human-friendly explanation of the purpose
|
|
13
|
+
attribute(:description)
|
|
14
|
+
# @!attribute purpose
|
|
15
|
+
# @return [Symbol, nil] the purpose of the maker. Can be used as an identifier in your implementation
|
|
16
|
+
attribute(:purpose)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -15,17 +15,17 @@ module PgEventstore
|
|
|
15
15
|
# @param stream [PgEventstore::Stream]
|
|
16
16
|
# @return [Boolean] whether a stream was deleted successfully
|
|
17
17
|
def delete_stream(stream)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
).call(stream)
|
|
18
|
+
Utils.assert_node_role!(config, Config::NodeRole.maintainable)
|
|
19
|
+
queries = Queries.new(maintenance: maintenance_queries)
|
|
20
|
+
Commands::DeleteStream.new(queries).call(stream)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# @param event [PgEventstore::Event] persisted event
|
|
24
24
|
# @return [Boolean] whether an event was deleted successfully
|
|
25
25
|
def delete_event(event, force: false)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
).call(event, force:)
|
|
26
|
+
Utils.assert_node_role!(config, Config::NodeRole.maintainable)
|
|
27
|
+
queries = Queries.new(maintenance: maintenance_queries, events_global_index: events_global_index_queries)
|
|
28
|
+
Commands::DeleteEvent.new(queries).call(event, force:)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
private
|
|
@@ -44,5 +44,10 @@ module PgEventstore
|
|
|
44
44
|
def connection
|
|
45
45
|
PgEventstore.connection(config.name)
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
# @return [PgEventstore::EventsGlobalIndexQueries]
|
|
49
|
+
def events_global_index_queries
|
|
50
|
+
EventsGlobalIndexQueries.new(connection, QueryStrategy::Foreground.new(connection))
|
|
51
|
+
end
|
|
47
52
|
end
|
|
48
53
|
end
|