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.
Files changed (303) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/CHANGELOG.md +186 -20
  4. data/README.md +25 -15
  5. data/db/migrations/10_setup_pg_cron.rb +1 -23
  6. data/db/migrations/15_create_streams_global_index.sql +17 -0
  7. data/db/migrations/16_populate_streams_global_index.rb +150 -0
  8. data/db/migrations/17_create_events_global_index.sql +62 -0
  9. data/db/migrations/18_populate_events_global_index.rb +124 -0
  10. data/db/migrations/19_populate_events_global_index_p2.rb +25 -0
  11. data/db/migrations/20_migrate_subscriptions_current_position.sql +19 -0
  12. data/db/migrations/21_create_partitions_stats.sql +2 -0
  13. data/db/migrations/22_drop_streams_sql_view.sql +2 -0
  14. data/db/migrations/23_adjust_partitions_indexes.sql +5 -0
  15. data/db/migrations/24_drop_legacy_events_indexes.sql +3 -0
  16. data/db/migrations/25_add_parent_partitions_info_to_partitions.sql +16 -0
  17. data/db/migrations/26_change_events_stream_revision_type.rb +35 -0
  18. data/db/migrations/27_drop_events_horizon.sql +3 -0
  19. data/db/migrations/28_create_maintenance_tasks.sql +8 -0
  20. data/db/migrations/29_create_event_markers.sql +35 -0
  21. data/db/migrations/30_improve_partitions_search_in_admin_ui.rb +24 -0
  22. data/db/migrations/31_drop_events_id_default_value.sql +1 -0
  23. data/db/migrations/32_create_parittions_triggers.sql +101 -0
  24. data/docs/AGENTS.fragment.md +696 -0
  25. data/docs/admin_ui.md +3 -1
  26. data/docs/appending_events.md +110 -49
  27. data/docs/configuration.md +69 -36
  28. data/docs/event_tracing.md +55 -0
  29. data/docs/events_and_streams.md +54 -30
  30. data/docs/how_it_works.md +57 -16
  31. data/docs/linking_events.md +2 -1
  32. data/docs/maintenance.md +14 -5
  33. data/docs/multiple_commands.md +17 -8
  34. data/docs/reading_events.md +208 -43
  35. data/docs/reading_streams.md +50 -0
  36. data/docs/replication.md +99 -0
  37. data/docs/subscriptions.md +165 -35
  38. data/docs/writing_middleware.md +25 -8
  39. data/ext/pg_eventstore_ext/extconf.rb +5 -0
  40. data/ext/pg_eventstore_ext/pg_eventstore_ext.c +74 -0
  41. data/lib/pg_eventstore/async_runner.rb +63 -0
  42. data/lib/pg_eventstore/basic_config.rb +15 -0
  43. data/lib/pg_eventstore/chunks/chunk.rb +31 -0
  44. data/lib/pg_eventstore/chunks/read_api_events_index_chunk.rb +83 -0
  45. data/lib/pg_eventstore/chunks/replica_events_index_chunk.rb +35 -0
  46. data/lib/pg_eventstore/chunks/repository.rb +73 -0
  47. data/lib/pg_eventstore/chunks/subscription_checkpoint_chunk.rb +48 -0
  48. data/lib/pg_eventstore/chunks/subscription_events_index_chunk.rb +99 -0
  49. data/lib/pg_eventstore/chunks.rb +14 -0
  50. data/lib/pg_eventstore/client.rb +163 -50
  51. data/lib/pg_eventstore/commands/append.rb +62 -43
  52. data/lib/pg_eventstore/commands/delete_event.rb +7 -8
  53. data/lib/pg_eventstore/commands/delete_stream.rb +3 -3
  54. data/lib/pg_eventstore/commands/event_modifiers/prepare_link_event.rb +9 -7
  55. data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
  56. data/lib/pg_eventstore/commands/link_to.rb +5 -5
  57. data/lib/pg_eventstore/commands/read.rb +23 -5
  58. data/lib/pg_eventstore/commands/read_grouped.rb +46 -0
  59. data/lib/pg_eventstore/commands/read_streams.rb +18 -0
  60. data/lib/pg_eventstore/commands/read_streams_paginated.rb +56 -0
  61. data/lib/pg_eventstore/commands/regular_stream_read_paginated.rb +4 -4
  62. data/lib/pg_eventstore/commands/revision_check/current_revision.rb +51 -0
  63. data/lib/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rb +46 -0
  64. data/lib/pg_eventstore/commands/revision_check/expected_revision.rb +135 -0
  65. data/lib/pg_eventstore/commands/revision_check/stream_revision_check.rb +98 -0
  66. data/lib/pg_eventstore/commands/revision_check/stream_revision_comparison.rb +36 -0
  67. data/lib/pg_eventstore/commands/stream_revision.rb +14 -0
  68. data/lib/pg_eventstore/commands/system_stream_read_paginated.rb +4 -4
  69. data/lib/pg_eventstore/commands.rb +4 -2
  70. data/lib/pg_eventstore/config.rb +30 -9
  71. data/lib/pg_eventstore/connection.rb +21 -2
  72. data/lib/pg_eventstore/errors.rb +136 -10
  73. data/lib/pg_eventstore/event.rb +34 -2
  74. data/lib/pg_eventstore/event_deserializer.rb +5 -4
  75. data/lib/pg_eventstore/event_global_index.rb +118 -0
  76. data/lib/pg_eventstore/event_marker.rb +16 -0
  77. data/lib/pg_eventstore/event_marker_index.rb +25 -0
  78. data/lib/pg_eventstore/event_serializer.rb +6 -0
  79. data/lib/pg_eventstore/extensions/acts_as_configurable.rb +88 -0
  80. data/lib/pg_eventstore/extensions/options_defaults.rb +25 -0
  81. data/lib/pg_eventstore/extensions/options_extension.rb +2 -2
  82. data/lib/pg_eventstore/feature_marker.rb +18 -0
  83. data/lib/pg_eventstore/maintenance.rb +11 -6
  84. data/lib/pg_eventstore/middleware/event_tracing.rb +53 -0
  85. data/lib/pg_eventstore/partition.rb +6 -0
  86. data/lib/pg_eventstore/pg_connection.rb +70 -14
  87. data/lib/pg_eventstore/queries/event_marker_queries.rb +74 -0
  88. data/lib/pg_eventstore/queries/event_queries.rb +7 -93
  89. data/lib/pg_eventstore/queries/events_global_index_queries.rb +131 -0
  90. data/lib/pg_eventstore/queries/index_filtering_queries.rb +179 -0
  91. data/lib/pg_eventstore/queries/links_resolver.rb +4 -4
  92. data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
  93. data/lib/pg_eventstore/queries/partition_queries.rb +45 -103
  94. data/lib/pg_eventstore/queries/replica_queries.rb +110 -0
  95. data/lib/pg_eventstore/queries/streams_global_index_queries.rb +163 -0
  96. data/lib/pg_eventstore/queries/transaction_queries.rb +52 -10
  97. data/lib/pg_eventstore/queries.rb +29 -1
  98. data/lib/pg_eventstore/query_builders/basic_filtering.rb +38 -5
  99. data/lib/pg_eventstore/query_builders/event_markers_filtering.rb +47 -0
  100. data/lib/pg_eventstore/query_builders/event_markers_index_filtering.rb +275 -0
  101. data/lib/pg_eventstore/query_builders/event_subscription_positions_filtering.rb +37 -0
  102. data/lib/pg_eventstore/query_builders/events_filtering.rb +15 -164
  103. data/lib/pg_eventstore/query_builders/events_global_index_filtering.rb +227 -0
  104. data/lib/pg_eventstore/query_builders/filters/collection.rb +324 -0
  105. data/lib/pg_eventstore/query_builders/filters/event_type_filter.rb +37 -0
  106. data/lib/pg_eventstore/query_builders/filters/filter_row.rb +54 -0
  107. data/lib/pg_eventstore/query_builders/filters/marker_filter.rb +20 -0
  108. data/lib/pg_eventstore/query_builders/filters/marker_filter_row.rb +49 -0
  109. data/lib/pg_eventstore/query_builders/filters/stream_filter.rb +48 -0
  110. data/lib/pg_eventstore/query_builders/index_based_events_filtering.rb +260 -0
  111. data/lib/pg_eventstore/query_builders/partitions_filtering.rb +175 -51
  112. data/lib/pg_eventstore/query_builders/read_cursor/stream_cursor.rb +122 -0
  113. data/lib/pg_eventstore/query_builders/streams_global_index_filtering.rb +83 -0
  114. data/lib/pg_eventstore/query_builders/subscription_events_filtering.rb +79 -0
  115. data/lib/pg_eventstore/query_strategy/async.rb +64 -0
  116. data/lib/pg_eventstore/query_strategy/foreground.rb +25 -0
  117. data/lib/pg_eventstore/query_strategy.rb +19 -0
  118. data/lib/pg_eventstore/raw_event.rb +46 -0
  119. data/lib/pg_eventstore/rspec/test_helpers.rb +21 -8
  120. data/lib/pg_eventstore/sql_builder.rb +87 -8
  121. data/lib/pg_eventstore/stream.rb +13 -16
  122. data/lib/pg_eventstore/stream_global_index.rb +28 -0
  123. data/lib/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rb +5 -17
  124. data/lib/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rb +36 -0
  125. data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rb +12 -0
  126. data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +21 -7
  127. data/lib/pg_eventstore/subscriptions/events_processor.rb +20 -18
  128. data/lib/pg_eventstore/subscriptions/events_processor_consumer/multiple.rb +63 -0
  129. data/lib/pg_eventstore/subscriptions/events_processor_consumer/replica.rb +68 -0
  130. data/lib/pg_eventstore/subscriptions/events_processor_consumer/single.rb +62 -0
  131. data/lib/pg_eventstore/subscriptions/events_processor_consumer.rb +44 -0
  132. data/lib/pg_eventstore/subscriptions/events_subscription_position_worker.rb +68 -0
  133. data/lib/pg_eventstore/subscriptions/queries/event_subscription_position_queries.rb +177 -0
  134. data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +78 -54
  135. data/lib/pg_eventstore/subscriptions/replica_subscription_handler.rb +140 -0
  136. data/lib/pg_eventstore/subscriptions/replica_subscription_runner.rb +9 -0
  137. data/lib/pg_eventstore/subscriptions/subscription.rb +2 -1
  138. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/collection.rb +36 -0
  139. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/index_read_strategy.rb +82 -0
  140. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/replication_strategy.rb +75 -0
  141. data/lib/pg_eventstore/subscriptions/subscription_feed_strategy.rb +31 -0
  142. data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +24 -0
  143. data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +4 -2
  144. data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -9
  145. data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
  146. data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +9 -18
  147. data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
  148. data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +74 -14
  149. data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
  150. data/lib/pg_eventstore/tasks/setup.rake +2 -2
  151. data/lib/pg_eventstore/utils.rb +31 -0
  152. data/lib/pg_eventstore/version.rb +1 -1
  153. data/lib/pg_eventstore/web/application.rb +100 -16
  154. data/lib/pg_eventstore/web/paginator/base_collection.rb +5 -1
  155. data/lib/pg_eventstore/web/paginator/event_types_collection.rb +14 -4
  156. data/lib/pg_eventstore/web/paginator/events_collection.rb +29 -33
  157. data/lib/pg_eventstore/web/paginator/helpers.rb +16 -9
  158. data/lib/pg_eventstore/web/paginator/markers_collection.rb +48 -0
  159. data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +13 -2
  160. data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +21 -11
  161. data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +18 -4
  162. data/lib/pg_eventstore/web/paginator/streams_collection.rb +95 -0
  163. data/lib/pg_eventstore/web/public/javascripts/pg_eventstore.js +49 -22
  164. data/lib/pg_eventstore/web/subscriptions/set_collection.rb +1 -1
  165. data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +1 -1
  166. data/lib/pg_eventstore/web/subscriptions/with_state/set_collection.rb +1 -1
  167. data/lib/pg_eventstore/web/subscriptions/with_state/subscriptions.rb +1 -1
  168. data/lib/pg_eventstore/web/views/home/dashboard.erb +11 -9
  169. data/lib/pg_eventstore/web/views/home/partials/event_filter.erb +18 -5
  170. data/lib/pg_eventstore/web/views/home/partials/events.erb +38 -1
  171. data/lib/pg_eventstore/web/views/home/partials/markers_filter.erb +18 -0
  172. data/lib/pg_eventstore/web/views/layouts/application.erb +6 -0
  173. data/lib/pg_eventstore/web/views/streams/index.erb +110 -0
  174. data/lib/pg_eventstore/web/views/streams/partials/streams.erb +11 -0
  175. data/lib/pg_eventstore/web/views/subscriptions/index.erb +4 -1
  176. data/lib/pg_eventstore/web.rb +2 -0
  177. data/lib/pg_eventstore.rb +23 -60
  178. data/pg_eventstore.gemspec +6 -4
  179. data/sig/interfaces/_raw_events_handler.rbs +3 -0
  180. data/sig/interfaces/subscription_handler.rbs +1 -1
  181. data/sig/pg/result.rbs +9 -0
  182. data/sig/pg_eventstore/async_runner.rbs +13 -0
  183. data/sig/pg_eventstore/basic_config.rbs +9 -0
  184. data/sig/pg_eventstore/chunks/chunk.rbs +13 -0
  185. data/sig/pg_eventstore/chunks/read_api_events_index_chunk.rbs +30 -0
  186. data/sig/pg_eventstore/chunks/replica_events_index_chunk.rbs +11 -0
  187. data/sig/pg_eventstore/chunks/repository.rbs +22 -0
  188. data/sig/pg_eventstore/chunks/subscription_checkpoint_chunk.rbs +18 -0
  189. data/sig/pg_eventstore/chunks/subscription_events_index_chunk.rbs +37 -0
  190. data/sig/pg_eventstore/client.rbs +40 -42
  191. data/sig/pg_eventstore/commands/append.rbs +11 -25
  192. data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +9 -12
  193. data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +5 -4
  194. data/sig/pg_eventstore/commands/link_to.rbs +6 -11
  195. data/sig/pg_eventstore/commands/read.rbs +2 -5
  196. data/sig/pg_eventstore/commands/read_grouped.rbs +7 -0
  197. data/sig/pg_eventstore/commands/read_streams.rbs +7 -0
  198. data/sig/pg_eventstore/commands/read_streams_paginated.rbs +16 -0
  199. data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +9 -17
  200. data/sig/pg_eventstore/commands/revision_check/current_revision.rbs +25 -0
  201. data/sig/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rbs +14 -0
  202. data/sig/pg_eventstore/commands/revision_check/expected_revision.rbs +67 -0
  203. data/sig/pg_eventstore/commands/revision_check/stream_revision_check.rbs +20 -0
  204. data/sig/pg_eventstore/commands/revision_check/stream_revision_comparison.rbs +9 -0
  205. data/sig/pg_eventstore/commands/stream_revision.rbs +7 -0
  206. data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +9 -14
  207. data/sig/pg_eventstore/config.rbs +15 -6
  208. data/sig/pg_eventstore/connection.rbs +11 -18
  209. data/sig/pg_eventstore/errors.rbs +64 -34
  210. data/sig/pg_eventstore/event.rbs +16 -2
  211. data/sig/pg_eventstore/event_deserializer.rbs +5 -10
  212. data/sig/pg_eventstore/event_global_index.rbs +60 -0
  213. data/sig/pg_eventstore/event_marker.rbs +9 -0
  214. data/sig/pg_eventstore/event_marker_index.rbs +12 -0
  215. data/sig/pg_eventstore/extensions/acts_as_configurable.rbs +29 -0
  216. data/sig/pg_eventstore/extensions/options_defaults.rbs +7 -0
  217. data/sig/pg_eventstore/feature_marker.rbs +10 -0
  218. data/sig/pg_eventstore/maintenance.rbs +12 -8
  219. data/sig/pg_eventstore/middleware/event_trace.rbs +14 -0
  220. data/sig/pg_eventstore/partition.rbs +2 -4
  221. data/sig/pg_eventstore/pg_connection.rbs +8 -0
  222. data/sig/pg_eventstore/queries/event_marker_queries.rbs +21 -0
  223. data/sig/pg_eventstore/queries/event_queries.rbs +4 -36
  224. data/sig/pg_eventstore/queries/events_global_index_queries.rbs +37 -0
  225. data/sig/pg_eventstore/queries/index_filtering_queries.rbs +50 -0
  226. data/sig/pg_eventstore/queries/links_resolver.rbs +5 -9
  227. data/sig/pg_eventstore/queries/maintenance_queries.rbs +12 -9
  228. data/sig/pg_eventstore/queries/partition_queries.rbs +32 -67
  229. data/sig/pg_eventstore/queries/replica_queries.rbs +31 -0
  230. data/sig/pg_eventstore/queries/streams_global_index_queries.rbs +39 -0
  231. data/sig/pg_eventstore/queries/transaction_queries.rbs +2 -0
  232. data/sig/pg_eventstore/queries.rbs +11 -21
  233. data/sig/pg_eventstore/query_builders/basic_filtering.rbs +10 -3
  234. data/sig/pg_eventstore/query_builders/event_markers_filtering.rbs +17 -0
  235. data/sig/pg_eventstore/query_builders/event_markers_index_filtering.rbs +69 -0
  236. data/sig/pg_eventstore/query_builders/event_subscription_positions_filtering.rbs +15 -0
  237. data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +9 -51
  238. data/sig/pg_eventstore/query_builders/events_global_index_filtering.rbs +68 -0
  239. data/sig/pg_eventstore/query_builders/filters/collection.rbs +84 -0
  240. data/sig/pg_eventstore/query_builders/filters/event_type_filter.rbs +19 -0
  241. data/sig/pg_eventstore/query_builders/filters/filter_row.rbs +21 -0
  242. data/sig/pg_eventstore/query_builders/filters/marker_filter.rbs +13 -0
  243. data/sig/pg_eventstore/query_builders/filters/marker_filter_row.rbs +19 -0
  244. data/sig/pg_eventstore/query_builders/filters/stream_filter.rbs +24 -0
  245. data/sig/pg_eventstore/query_builders/index_based_events_filtering.rbs +60 -0
  246. data/sig/pg_eventstore/query_builders/partitions_filtering.rbs +29 -10
  247. data/sig/pg_eventstore/query_builders/read_cursor/stream_cursor.rbs +47 -0
  248. data/sig/pg_eventstore/query_builders/streams_global_index_filtering.rbs +27 -0
  249. data/sig/pg_eventstore/query_builders/subscription_events_filtering.rbs +26 -0
  250. data/sig/pg_eventstore/query_strategy/async.rbs +17 -0
  251. data/sig/pg_eventstore/query_strategy/foreground.rbs +11 -0
  252. data/sig/pg_eventstore/query_strategy.rbs +7 -0
  253. data/sig/pg_eventstore/raw_event.rbs +20 -0
  254. data/sig/pg_eventstore/sql_builder.rbs +32 -10
  255. data/sig/pg_eventstore/stream.rbs +10 -18
  256. data/sig/pg_eventstore/stream_global_index.rbs +14 -0
  257. data/sig/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rbs +5 -4
  258. data/sig/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rbs +9 -0
  259. data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rbs +17 -12
  260. data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rbs +17 -6
  261. data/sig/pg_eventstore/subscriptions/event_subscription_position_queries.rbs +30 -0
  262. data/sig/pg_eventstore/subscriptions/events_processor.rbs +12 -5
  263. data/sig/pg_eventstore/subscriptions/events_processor_consumer/multiple.rbs +17 -0
  264. data/sig/pg_eventstore/subscriptions/events_processor_consumer/replica.rbs +17 -0
  265. data/sig/pg_eventstore/subscriptions/events_processor_consumer/single.rbs +17 -0
  266. data/sig/pg_eventstore/subscriptions/events_processor_consumer.rbs +14 -0
  267. data/sig/pg_eventstore/subscriptions/events_subscription_position_worker.rbs +28 -0
  268. data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +7 -39
  269. data/sig/pg_eventstore/subscriptions/replica_subscription_handler.rbs +33 -0
  270. data/sig/pg_eventstore/subscriptions/replica_subscription_runner.rbs +4 -0
  271. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/collection.rbs +14 -0
  272. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/index_read_strategy.rbs +23 -0
  273. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/replication_strategy.rbs +23 -0
  274. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy.rbs +11 -0
  275. data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +13 -10
  276. data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +1 -1
  277. data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +13 -2
  278. data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +1 -8
  279. data/sig/pg_eventstore/subscriptions/subscriptions_lifecycle.rbs +4 -6
  280. data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +29 -43
  281. data/sig/pg_eventstore/synchronized_array.rbs +4 -0
  282. data/sig/pg_eventstore/utils.rbs +10 -11
  283. data/sig/pg_eventstore/web/application.rbs +13 -3
  284. data/sig/pg_eventstore/web/paginator/base_collection.rbs +2 -0
  285. data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +4 -0
  286. data/sig/pg_eventstore/web/paginator/events_collection.rbs +11 -11
  287. data/sig/pg_eventstore/web/paginator/helpers.rbs +6 -15
  288. data/sig/pg_eventstore/web/paginator/markers_collection.rbs +13 -0
  289. data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +4 -0
  290. data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +4 -0
  291. data/sig/pg_eventstore/web/paginator/streams_collection.rbs +30 -0
  292. data/sig/pg_eventstore.rbs +8 -26
  293. metadata +175 -20
  294. data/Dockerfile +0 -3
  295. data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +0 -69
  296. data/lib/pg_eventstore/commands/regular_stream_read_grouped.rb +0 -31
  297. data/lib/pg_eventstore/subscriptions/queries/subscription_service_queries.rb +0 -78
  298. data/lib/pg_eventstore/web/views/home/partials/system_stream_filter.erb +0 -15
  299. data/sig/pg_eventstore/commands/all_stream_read_grouped.rbs +0 -16
  300. data/sig/pg_eventstore/commands/regular_stream_read_grouped.rbs +0 -8
  301. data/sig/pg_eventstore/subscriptions/queries/subscription_service_queries.rbs +0 -19
  302. data/sig/pg_eventstore/subscriptions/synchronized_array.rbs +0 -4
  303. /data/sig/interfaces/{_raw_event_handler.rbs → raw_event_handler.rbs} +0 -0
@@ -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
- def initialize(revision:, expected_revision:, stream:)
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
- if revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :stream_exists
74
- return expected_stream_exists
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 [Integer, String]
239
+ # @return [Object]
117
240
  attr_reader :id
118
241
 
119
242
  # @param table_name [String]
120
- # @param id [Integer, String]
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 with #{id.inspect} id."
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
@@ -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] UUIDv4 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<#deserialize, #serialize>]
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<Object<#deserialize, #serialize>>]
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 = without_middlewares.deserialize(attrs['link']) if attrs.key?('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.each_with_object({}) do |option, res|
177
- res[option.name] = public_send(option.name)
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
- Commands::DeleteStream.new(
19
- Queries.new(transactions: transaction_queries, maintenance: maintenance_queries)
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
- Commands::DeleteEvent.new(
27
- Queries.new(transactions: transaction_queries, maintenance: maintenance_queries)
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