pg_eventstore 1.13.1 → 1.13.2

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +126 -0
  3. data/CHANGELOG.md +4 -0
  4. data/exe/pg-eventstore +6 -6
  5. data/lib/pg_eventstore/abstract_command.rb +1 -1
  6. data/lib/pg_eventstore/callbacks.rb +7 -2
  7. data/lib/pg_eventstore/cli/commands/callback_handlers/start_cmd_handlers.rb +1 -0
  8. data/lib/pg_eventstore/cli/commands/start_subscriptions_command.rb +5 -4
  9. data/lib/pg_eventstore/cli/parser_options/metadata.rb +4 -4
  10. data/lib/pg_eventstore/cli/parsers/default_parser.rb +8 -8
  11. data/lib/pg_eventstore/cli/parsers/subscription_parser.rb +2 -2
  12. data/lib/pg_eventstore/cli/try_to_delete_subscriptions_set.rb +4 -1
  13. data/lib/pg_eventstore/cli.rb +4 -4
  14. data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +2 -2
  15. data/lib/pg_eventstore/commands/event_modifiers/prepare_link_event.rb +1 -0
  16. data/lib/pg_eventstore/commands/link_to.rb +4 -5
  17. data/lib/pg_eventstore/commands/multiple.rb +1 -3
  18. data/lib/pg_eventstore/commands/regular_stream_read_paginated.rb +1 -1
  19. data/lib/pg_eventstore/config.rb +1 -1
  20. data/lib/pg_eventstore/connection.rb +4 -1
  21. data/lib/pg_eventstore/errors.rb +3 -1
  22. data/lib/pg_eventstore/extensions/callbacks_extension.rb +2 -0
  23. data/lib/pg_eventstore/extensions/options_extension.rb +10 -10
  24. data/lib/pg_eventstore/extensions/using_connection_extension.rb +1 -1
  25. data/lib/pg_eventstore/pg_connection.rb +7 -5
  26. data/lib/pg_eventstore/queries/event_queries.rb +11 -10
  27. data/lib/pg_eventstore/queries/partition_queries.rb +4 -4
  28. data/lib/pg_eventstore/queries/transaction_queries.rb +5 -9
  29. data/lib/pg_eventstore/query_builders/events_filtering.rb +13 -13
  30. data/lib/pg_eventstore/query_builders/partitions_filtering.rb +6 -8
  31. data/lib/pg_eventstore/rspec/has_option_matcher.rb +12 -13
  32. data/lib/pg_eventstore/rspec/test_helpers.rb +4 -3
  33. data/lib/pg_eventstore/sql_builder.rb +9 -13
  34. data/lib/pg_eventstore/stream.rb +8 -8
  35. data/lib/pg_eventstore/subscriptions/basic_runner.rb +4 -3
  36. data/lib/pg_eventstore/subscriptions/commands_handler.rb +1 -1
  37. data/lib/pg_eventstore/subscriptions/events_processor.rb +1 -1
  38. data/lib/pg_eventstore/subscriptions/extensions/base_command_extension.rb +10 -8
  39. data/lib/pg_eventstore/subscriptions/queries/subscription_command_queries.rb +23 -21
  40. data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +11 -8
  41. data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rb +8 -13
  42. data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rb +7 -6
  43. data/lib/pg_eventstore/subscriptions/runner_recovery_strategies/restore_connection.rb +3 -1
  44. data/lib/pg_eventstore/subscriptions/runner_recovery_strategies/restore_subscription_runner.rb +1 -0
  45. data/lib/pg_eventstore/subscriptions/runner_state.rb +3 -1
  46. data/lib/pg_eventstore/subscriptions/subscription.rb +11 -10
  47. data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +1 -1
  48. data/lib/pg_eventstore/subscriptions/subscription_runner.rb +1 -1
  49. data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +5 -7
  50. data/lib/pg_eventstore/subscriptions/subscriptions_set.rb +8 -8
  51. data/lib/pg_eventstore/subscriptions/subscriptions_set_lifecycle.rb +2 -0
  52. data/lib/pg_eventstore/tasks/setup.rake +7 -6
  53. data/lib/pg_eventstore/utils.rb +8 -4
  54. data/lib/pg_eventstore/version.rb +1 -1
  55. data/lib/pg_eventstore/web/application.rb +22 -15
  56. data/lib/pg_eventstore/web/paginator/event_types_collection.rb +9 -11
  57. data/lib/pg_eventstore/web/paginator/events_collection.rb +6 -7
  58. data/lib/pg_eventstore/web/paginator/helpers.rb +19 -19
  59. data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +9 -9
  60. data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +9 -10
  61. data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +9 -11
  62. data/lib/pg_eventstore/web/subscriptions/set_collection.rb +1 -1
  63. data/lib/pg_eventstore/web/subscriptions/subscriptions_to_set_association.rb +2 -0
  64. data/lib/pg_eventstore/web/subscriptions/with_state/set_collection.rb +1 -1
  65. data/lib/pg_eventstore.rb +3 -11
  66. data/pg_eventstore.gemspec +19 -19
  67. data/sig/pg_eventstore/client.rbs +4 -8
  68. data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +2 -0
  69. data/sig/pg_eventstore/web/application.rbs +2 -0
  70. metadata +8 -7
@@ -7,7 +7,7 @@ module PgEventstore
7
7
  include Extensions::CallbacksExtension
8
8
 
9
9
  # @return [Hash<Symbol => String>]
10
- STATES = %i(initial running halting stopped dead).to_h { [_1, _1.to_s.freeze] }.freeze
10
+ STATES = %i[initial running halting stopped dead].to_h { [_1, _1.to_s.freeze] }.freeze
11
11
 
12
12
  def initialize
13
13
  initial!
@@ -36,11 +36,13 @@ module PgEventstore
36
36
 
37
37
  # @param state [String]
38
38
  # @return [String]
39
+ # rubocop:disable Naming/AccessorMethodName
39
40
  def set_state(state)
40
41
  old_state = @state
41
42
  @state = state
42
43
  callbacks.run_callbacks(:change_state, @state) unless old_state == @state
43
44
  @state
44
45
  end
46
+ # rubocop:enable Naming/AccessorMethodName
45
47
  end
46
48
  end
@@ -26,10 +26,11 @@ module PgEventstore
26
26
  # the list of available options
27
27
  attribute(:options)
28
28
  # @!attribute current_position
29
- # @return [Integer, nil] current Subscription's position. It is updated automatically each time an event is processed
29
+ # @return [Integer, nil] current Subscription's position. It is updated automatically each time an event is
30
+ # processed
30
31
  attribute(:current_position)
31
32
  # @!attribute state
32
- # @return [String, nil] current Subscription's state. It is updated automatically during Subscription's life cycle.
33
+ # @return [String, nil] current Subscription's state. It is updated automatically during Subscription's life cycle
33
34
  # See {RunnerState::STATES} for possible values.
34
35
  attribute(:state)
35
36
  # @!attribute average_event_processing_time
@@ -141,20 +142,20 @@ module PgEventstore
141
142
  id.hash
142
143
  end
143
144
 
144
- # @param another [Object]
145
+ # @param other [Object]
145
146
  # @return [Boolean]
146
- def eql?(another)
147
- return false unless another.is_a?(Subscription)
147
+ def eql?(other)
148
+ return false unless other.is_a?(Subscription)
148
149
 
149
- hash == another.hash
150
+ hash == other.hash
150
151
  end
151
152
 
152
- # @param another [Object]
153
+ # @param other [Object]
153
154
  # @return [Boolean]
154
- def ==(another)
155
- return false unless another.is_a?(Subscription)
155
+ def ==(other)
156
+ return false unless other.is_a?(Subscription)
156
157
 
157
- id == another.id
158
+ id == other.id
158
159
  end
159
160
 
160
161
  private
@@ -34,7 +34,7 @@ module PgEventstore
34
34
  # The average time required to process an event.
35
35
  # @return [Float]
36
36
  def average_event_processing_time
37
- synchronize { @timings.size.zero? ? 0.0 : @timings.sum / @timings.size }
37
+ synchronize { @timings.empty? ? 0.0 : @timings.sum / @timings.size }
38
38
  end
39
39
  end
40
40
  end
@@ -58,7 +58,7 @@ module PgEventstore
58
58
 
59
59
  # @return [Integer]
60
60
  def estimate_events_number
61
- return INITIAL_EVENTS_PER_CHUNK if @stats.average_event_processing_time.zero?
61
+ return INITIAL_EVENTS_PER_CHUNK if @stats.average_event_processing_time == 0
62
62
 
63
63
  events_per_chunk = (@subscription.chunk_query_interval / @stats.average_event_processing_time).round
64
64
  events_to_fetch = [events_per_chunk, MAX_EVENTS_PER_CHUNK].min - @events_processor.events_left_in_chunk
@@ -54,7 +54,7 @@ module PgEventstore
54
54
  {
55
55
  name: set_name,
56
56
  max_restarts_number: max_retries || config.subscriptions_set_max_retries,
57
- time_between_restarts: retries_interval || config.subscriptions_set_retries_interval
57
+ time_between_restarts: retries_interval || config.subscriptions_set_retries_interval,
58
58
  }
59
59
  )
60
60
  @subscriptions_lifecycle = SubscriptionsLifecycle.new(
@@ -108,7 +108,7 @@ module PgEventstore
108
108
  graceful_shutdown_timeout: graceful_shutdown_timeout,
109
109
  recovery_strategies: recovery_strategies(subscription, restart_terminator, failed_subscription_notifier)
110
110
  ),
111
- subscription: subscription,
111
+ subscription: subscription
112
112
  )
113
113
 
114
114
  @subscriptions_lifecycle.runners.push(runner)
@@ -149,12 +149,10 @@ module PgEventstore
149
149
  private
150
150
 
151
151
  # @return [Object] the result of the passed block
152
- def run_cli_callbacks
152
+ def run_cli_callbacks(&blk)
153
153
  return yield unless defined?(::PgEventstore::CLI)
154
154
 
155
- PgEventstore::CLI.callbacks.run_callbacks(:start_manager, self) do
156
- yield
157
- end
155
+ PgEventstore::CLI.callbacks.run_callbacks(:start_manager, self, &blk)
158
156
  end
159
157
 
160
158
  # @param middlewares [Array<Symbol>, nil]
@@ -183,7 +181,7 @@ module PgEventstore
183
181
  RunnerRecoveryStrategies::RestoreSubscriptionRunner.new(
184
182
  subscription: subscription,
185
183
  restart_terminator: restart_terminator,
186
- failed_subscription_notifier: failed_subscription_notifier,
184
+ failed_subscription_notifier: failed_subscription_notifier
187
185
  ),
188
186
  ]
189
187
  end
@@ -92,20 +92,20 @@ module PgEventstore
92
92
  id.hash
93
93
  end
94
94
 
95
- # @param another [Object]
95
+ # @param other [Object]
96
96
  # @return [Boolean]
97
- def eql?(another)
98
- return false unless another.is_a?(SubscriptionsSet)
97
+ def eql?(other)
98
+ return false unless other.is_a?(SubscriptionsSet)
99
99
 
100
- hash == another.hash
100
+ hash == other.hash
101
101
  end
102
102
 
103
- # @param another [Object]
103
+ # @param other [Object]
104
104
  # @return [Boolean]
105
- def ==(another)
106
- return false unless another.is_a?(SubscriptionsSet)
105
+ def ==(other)
106
+ return false unless other.is_a?(SubscriptionsSet)
107
107
 
108
- id == another.id
108
+ id == other.id
109
109
  end
110
110
 
111
111
  private
@@ -27,9 +27,11 @@ module PgEventstore
27
27
  end
28
28
 
29
29
  # @return [PgEventstore::SubscriptionsSet]
30
+ # rubocop:disable Naming/MemoizedInstanceVariableName
30
31
  def persisted_subscriptions_set
31
32
  @subscriptions_set ||= SubscriptionsSet.using_connection(@config_name).create(@subscriptions_set_attrs)
32
33
  end
34
+ # rubocop:enable Naming/MemoizedInstanceVariableName
33
35
 
34
36
  # @return [void]
35
37
  def reset_subscriptions_set
@@ -14,13 +14,13 @@ helpers = Class.new do
14
14
  end
15
15
 
16
16
  def db_name
17
- @db_name ||= URI.parse(ENV.fetch('PG_EVENTSTORE_URI')).path&.delete("/")
17
+ @db_name ||= URI.parse(ENV.fetch('PG_EVENTSTORE_URI')).path&.delete('/')
18
18
  end
19
19
  end
20
20
  end
21
21
 
22
22
  namespace :pg_eventstore do
23
- desc "Creates events table, indexes, etc."
23
+ desc 'Creates events table, indexes, etc.'
24
24
  task :create do
25
25
  PgEventstore.configure do |config|
26
26
  config.pg_uri = helpers.postgres_uri
@@ -28,7 +28,8 @@ namespace :pg_eventstore do
28
28
 
29
29
  PgEventstore.connection.with do |conn|
30
30
  exists =
31
- conn.exec_params("SELECT 1 as exists FROM pg_database where datname = $1", [helpers.db_name]).first&.dig('exists')
31
+ conn.exec_params('SELECT 1 as exists FROM pg_database where datname = $1', [helpers.db_name]).
32
+ first&.dig('exists')
32
33
  if exists
33
34
  puts "#{helpers.db_name} already exists. Skipping."
34
35
  else
@@ -42,7 +43,7 @@ namespace :pg_eventstore do
42
43
  config.pg_uri = ENV['PG_EVENTSTORE_URI']
43
44
  end
44
45
 
45
- migration_files_root = "#{Gem::Specification.find_by_name("pg_eventstore").gem_dir}/db/migrations"
46
+ migration_files_root = "#{Gem::Specification.find_by_name('pg_eventstore').gem_dir}/db/migrations"
46
47
 
47
48
  PgEventstore.connection.with do |conn|
48
49
  conn.exec('CREATE TABLE IF NOT EXISTS migrations (number int NOT NULL)')
@@ -50,7 +51,7 @@ namespace :pg_eventstore do
50
51
  conn.exec('SELECT number FROM migrations ORDER BY number DESC LIMIT 1').to_a.dig(0, 'number') || -1
51
52
 
52
53
  Dir.chdir migration_files_root do
53
- Dir["*.{sql,rb}"].sort_by { |f_name| f_name.split('_').first.to_i }.each do |f_name|
54
+ Dir['*.{sql,rb}'].sort_by { |f_name| f_name.split('_').first.to_i }.each do |f_name|
54
55
  number = File.basename(f_name).split('_')[0].to_i
55
56
  next if latest_migration >= number
56
57
 
@@ -65,7 +66,7 @@ namespace :pg_eventstore do
65
66
  end
66
67
  end
67
68
 
68
- desc "Drops events table and related pg_eventstore objects."
69
+ desc 'Drops events table and related pg_eventstore objects.'
69
70
  task :drop do
70
71
  PgEventstore.configure do |config|
71
72
  config.pg_uri = helpers.postgres_uri
@@ -50,7 +50,7 @@ module PgEventstore
50
50
  {
51
51
  class: original_error.class,
52
52
  message: original_error.message,
53
- backtrace: original_error.backtrace
53
+ backtrace: original_error.backtrace,
54
54
  }.tap do |attrs|
55
55
  attrs.merge!(error.extra) if error.is_a?(WrappedException)
56
56
  end
@@ -61,7 +61,7 @@ module PgEventstore
61
61
  def underscore_str(str)
62
62
  str = str.dup
63
63
  str[0] = str[0].downcase
64
- str.gsub!(/[A-Z]/) { |letter| '_' + letter.downcase }
64
+ str.gsub!(/[A-Z]/) { |letter| "_#{letter.downcase}" }
65
65
  str
66
66
  end
67
67
 
@@ -83,7 +83,7 @@ module PgEventstore
83
83
  # @param content [String]
84
84
  # @return [void]
85
85
  def write_to_file(file_path, content)
86
- file = File.open(file_path, "w")
86
+ file = File.open(file_path, 'w')
87
87
  file.write(content)
88
88
  ensure
89
89
  file&.close
@@ -91,20 +91,24 @@ module PgEventstore
91
91
 
92
92
  # @param file_path [String]
93
93
  # @return [void]
94
+ # rubocop:disable Lint/SuppressedException
94
95
  def remove_file(file_path)
95
96
  File.delete(file_path)
96
97
  rescue Errno::ENOENT
97
98
  end
99
+ # rubocop:enable Lint/SuppressedException
98
100
 
99
101
  # @param file_path [String]
100
102
  # @return [String, nil]
103
+ # rubocop:disable Lint/SuppressedException
101
104
  def read_pid(file_path)
102
- file = File.open(file_path, "r")
105
+ file = File.open(file_path, 'r')
103
106
  file.readline.strip
104
107
  rescue Errno::ENOENT
105
108
  ensure
106
109
  file&.close
107
110
  end
111
+ # rubocop:enable Lint/SuppressedException
108
112
 
109
113
  # @param exception [StandardError]
110
114
  # @param extra [Hash] additional exception info
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PgEventstore
4
4
  # @return [String]
5
- VERSION = "1.13.1"
5
+ VERSION = '1.13.2'
6
6
  end
@@ -13,26 +13,33 @@ module PgEventstore
13
13
  COOKIES_CONFIG_KEY = 'current_config'
14
14
  # @return [String]
15
15
  COOKIES_FLASH_MESSAGE_KEY = 'flash_message'
16
+ # @return [Array<Symbol>]
17
+ LOGGING_ENVS = %i[development test].freeze
18
+ private_constant :LOGGING_ENVS
16
19
 
17
20
  # Defines a replacement for empty string value in a stream attributes filter or in an event type filter. This
18
21
  # replacement is needed to differentiate a user selection vs default placeholder value.
19
22
  # @return [String]
20
- EMPTY_STRING_SIGN = "\x00".freeze
23
+ EMPTY_STRING_SIGN = "\x00"
21
24
 
22
- set :static_cache_control, [:private, max_age: 86400]
25
+ set :static_cache_control, [:private, { max_age: 86_400 }]
23
26
  set :environment, -> { (ENV['RACK_ENV'] || ENV['RAILS_ENV'] || ENV['APP_ENV'])&.to_sym || :development }
24
- set :logging, -> { environment == :development || environment == :test }
27
+ set :logging, -> { LOGGING_ENVS.include?(environment) }
25
28
  set :erb, layout: :'layouts/application'
26
29
  set :host_authorization, { allow_if: ->(_env) { true } }
27
30
 
28
31
  helpers(Paginator::Helpers, Subscriptions::Helpers) do
29
32
  # @return [Array<Hash>, nil]
33
+ # rubocop:disable Style/HashConversion
30
34
  def streams_filter
31
35
  streams = QueryBuilders::EventsFiltering.extract_streams_filter(params)
32
- streams&.select { _1 in { context: String, stream_name: String, stream_id: String } }&.map do
33
- Hash[_1.reject { |_, value| value == '' }].transform_keys(&:to_sym)
34
- end&.reject { _1.empty? }
36
+ streams = streams.select { _1 in { context: String, stream_name: String, stream_id: String } }
37
+ streams = streams.map do |stream_attrs|
38
+ Hash[stream_attrs.reject { |_, value| value == '' }].transform_keys(&:to_sym)
39
+ end
40
+ streams.reject(&:empty?)
35
41
  end
42
+ # rubocop:enable Style/HashConversion
36
43
 
37
44
  # @return [String, nil]
38
45
  def system_stream
@@ -44,7 +51,7 @@ module PgEventstore
44
51
  def events_filter
45
52
  event_filters = { filter: { event_types: params.dig(:filter, :events) } }
46
53
  events = QueryBuilders::EventsFiltering.extract_event_types_filter(event_filters)
47
- events&.reject { _1 == '' }
54
+ events.reject { _1 == '' }
48
55
  end
49
56
 
50
57
  # @return [Symbol]
@@ -81,7 +88,7 @@ module PgEventstore
81
88
  end
82
89
  halt 200, {
83
90
  results: results,
84
- pagination: { more: !collection.next_page_starting_id.nil?, starting_id: collection.next_page_starting_id }
91
+ pagination: { more: !collection.next_page_starting_id.nil?, starting_id: collection.next_page_starting_id },
85
92
  }.to_json
86
93
  end
87
94
 
@@ -144,7 +151,7 @@ module PgEventstore
144
151
  order: Paginator::EventsCollection::SQL_DIRECTIONS[params[:order]],
145
152
  options: {
146
153
  filter: { event_types: events_filter, streams: streams_filter },
147
- resolve_link_tos: resolve_link_tos?
154
+ resolve_link_tos: resolve_link_tos?,
148
155
  },
149
156
  system_stream: system_stream
150
157
  )
@@ -154,7 +161,7 @@ module PgEventstore
154
161
  halt 200, {
155
162
  events: erb(:'home/partials/events', { layout: false }, { events: @collection.collection }),
156
163
  total_count: total_count(@collection.total_count),
157
- pagination: erb(:'home/partials/pagination_links', { layout: false }, { collection: @collection })
164
+ pagination: erb(:'home/partials/pagination_links', { layout: false }, { collection: @collection }),
158
165
  }.to_json
159
166
  else
160
167
  erb :'home/dashboard'
@@ -223,7 +230,7 @@ module PgEventstore
223
230
  options: {
224
231
  query: params[:term],
225
232
  context: unescape_empty_string(params[:context]),
226
- stream_name: unescape_empty_string(params[:stream_name])
233
+ stream_name: unescape_empty_string(params[:stream_name]),
227
234
  }
228
235
  )
229
236
  paginated_json_response(collection)
@@ -297,7 +304,7 @@ module PgEventstore
297
304
  PgEventstore.maintenance(current_config).delete_event(event, force: force)
298
305
  self.flash_message = {
299
306
  message: "An event at global position #{event.global_position} has been deleted successfully.",
300
- kind: 'success'
307
+ kind: 'success',
301
308
  }
302
309
  rescue TooManyRecordsToLockError => e
303
310
  text = <<~TEXT
@@ -319,10 +326,10 @@ module PgEventstore
319
326
  stream_id: params[:stream_id]&.to_s,
320
327
  }
321
328
 
322
- err_message = ->(attrs) {
329
+ err_message = lambda { |attrs|
323
330
  self.flash_message = {
324
331
  message: "Could not delete #{attrs}. It is not valid stream for deletion.",
325
- kind: 'error'
332
+ kind: 'error',
326
333
  }
327
334
  }
328
335
 
@@ -334,7 +341,7 @@ module PgEventstore
334
341
  PgEventstore.maintenance(current_config).delete_stream(stream)
335
342
  self.flash_message = {
336
343
  message: "Stream #{stream.to_hash} has been successfully deleted.",
337
- kind: 'success'
344
+ kind: 'success',
338
345
  }
339
346
  end
340
347
  else
@@ -9,14 +9,13 @@ module PgEventstore
9
9
 
10
10
  # @return [Array<Hash<String => String>>]
11
11
  def collection
12
- @_collection ||=
12
+ @collection ||=
13
13
  begin
14
- sql_builder =
15
- SQLBuilder.new.select('event_type').from('partitions').
16
- where('context is not null and stream_name is not null').
17
- group('event_type').order("event_type #{order}").limit(per_page)
14
+ sql_builder = SQLBuilder.new.select('event_type').from('partitions')
15
+ sql_builder.where('context is not null and stream_name is not null')
18
16
  sql_builder.where("event_type #{direction_operator} ?", starting_id) if starting_id
19
17
  sql_builder.where('event_type ilike ?', "%#{options[:query]}%")
18
+ sql_builder.group('event_type').order("event_type #{order}").limit(per_page)
20
19
  connection.with do |conn|
21
20
  conn.exec_params(*sql_builder.to_exec_params)
22
21
  end.to_a
@@ -28,12 +27,11 @@ module PgEventstore
28
27
  return unless collection.size == per_page
29
28
 
30
29
  starting_id = collection.first['event_type']
31
- sql_builder =
32
- SQLBuilder.new.select('event_type').from('partitions').
33
- where('context is not null and stream_name is not null').
34
- where("event_type #{direction_operator} ?", starting_id).
35
- where('event_type ilike ?', "%#{options[:query]}%").
36
- group('event_type').order("event_type #{order}").limit(1).offset(per_page)
30
+ sql_builder = SQLBuilder.new.select('event_type').from('partitions')
31
+ sql_builder.where('context is not null and stream_name is not null')
32
+ sql_builder.where("event_type #{direction_operator} ?", starting_id)
33
+ sql_builder.where('event_type ilike ?', "%#{options[:query]}%")
34
+ sql_builder.group('event_type').order("event_type #{order}").limit(1).offset(per_page)
37
35
 
38
36
  connection.with do |conn|
39
37
  conn.exec_params(*sql_builder.to_exec_params)
@@ -7,7 +7,7 @@ module PgEventstore
7
7
  # @return [Hash<String => Symbol>] SQL directions, string-to-symbol mapping
8
8
  SQL_DIRECTIONS = {
9
9
  'asc' => :asc,
10
- 'desc' => :desc
10
+ 'desc' => :desc,
11
11
  }.tap do |directions|
12
12
  directions.default = :desc
13
13
  end.freeze
@@ -32,7 +32,7 @@ module PgEventstore
32
32
 
33
33
  # @return [Array<PgEventstore::Event>]
34
34
  def collection
35
- @_collection ||= PgEventstore.client(config_name).read(
35
+ @collection ||= PgEventstore.client(config_name).read(
36
36
  @stream,
37
37
  options: options.merge(from_position: starting_id, max_count: per_page, direction: order)
38
38
  )
@@ -59,18 +59,17 @@ module PgEventstore
59
59
  ).to_sql_builder.unselect.select('global_position').offset(1)
60
60
  sql, params = sql_builder.to_exec_params
61
61
  sql = "SELECT * FROM (#{sql}) events ORDER BY global_position #{order} LIMIT 1"
62
- connection.with do |conn|
62
+ connection.with do |conn|
63
63
  conn.exec_params(sql, params)
64
64
  end.to_a.dig(0, 'global_position')
65
65
  end
66
66
 
67
67
  # @return [Integer]
68
68
  def total_count
69
- @_total_count ||=
69
+ @total_count ||=
70
70
  begin
71
- sql_builder =
72
- QueryBuilders::EventsFiltering.events_filtering(@stream, options).
73
- to_sql_builder.remove_limit.remove_group.remove_order
71
+ sql_builder = QueryBuilders::EventsFiltering.events_filtering(@stream, options).to_sql_builder
72
+ sql_builder.remove_limit.remove_group.remove_order
74
73
  count = estimate_count(sql_builder)
75
74
  return count if count > MAX_NUMBER_TO_COUNT
76
75
 
@@ -10,10 +10,10 @@ module PgEventstore
10
10
  id = collection.prev_page_starting_id
11
11
  disabled = id ? '' : 'disabled'
12
12
  <<~HTML
13
- <li class="page-item #{disabled}">
14
- <a class="page-link" href="#{build_starting_id_link(id)}" tabindex="-1">Previous</a>
15
- </li>
16
- HTML
13
+ <li class="page-item #{disabled}">
14
+ <a class="page-link" href="#{build_starting_id_link(id)}" tabindex="-1">Previous</a>
15
+ </li>
16
+ HTML
17
17
  end
18
18
 
19
19
  # @param collection [PgEventstore::Web::Paginator::BaseCollection]
@@ -22,20 +22,20 @@ module PgEventstore
22
22
  id = collection.next_page_starting_id
23
23
  disabled = id ? '' : 'disabled'
24
24
  <<~HTML
25
- <li class="page-item #{disabled}">
26
- <a class="page-link" href="#{build_starting_id_link(id)}" tabindex="-1">Next</a>
27
- </li>
28
- HTML
25
+ <li class="page-item #{disabled}">
26
+ <a class="page-link" href="#{build_starting_id_link(id)}" tabindex="-1">Next</a>
27
+ </li>
28
+ HTML
29
29
  end
30
30
 
31
31
  # @return [String]
32
32
  def first_page_link
33
33
  path = build_path(params.slice(*(params.keys - ['starting_id'])))
34
34
  <<~HTML
35
- <li class="page-item">
36
- <a class="page-link" href="#{path}" tabindex="-1">First</a>
37
- </li>
38
- HTML
35
+ <li class="page-item">
36
+ <a class="page-link" href="#{path}" tabindex="-1">First</a>
37
+ </li>
38
+ HTML
39
39
  end
40
40
 
41
41
  # @param per_page [String] string representation of items per page. E.g. "10", "20", etc.
@@ -59,9 +59,9 @@ module PgEventstore
59
59
  def total_count(number)
60
60
  prefix =
61
61
  if number > Paginator::EventsCollection::MAX_NUMBER_TO_COUNT
62
- "Estimate count: "
62
+ 'Estimate count: '
63
63
  else
64
- "Total count: "
64
+ 'Total count: '
65
65
  end
66
66
  number = number_with_delimiter(number)
67
67
  prefix + number
@@ -75,7 +75,7 @@ module PgEventstore
75
75
  number = number.to_s
76
76
  symbols_to_skip = number.size % 3
77
77
  parts = []
78
- parts.push(number[0...symbols_to_skip]) unless symbols_to_skip.zero?
78
+ parts.push(number[0...symbols_to_skip]) unless symbols_to_skip == 0
79
79
  parts.push(*number[symbols_to_skip..].scan(/\d{3}/))
80
80
  parts.join(delimiter)
81
81
  end
@@ -90,10 +90,10 @@ module PgEventstore
90
90
  {
91
91
  context: escape_empty_string(event.stream.context),
92
92
  stream_name: escape_empty_string(event.stream.stream_name),
93
- stream_id: escape_empty_string(event.stream.stream_id)
94
- }
95
- ]
96
- }
93
+ stream_id: escape_empty_string(event.stream.stream_id),
94
+ },
95
+ ],
96
+ },
97
97
  }
98
98
  )
99
99
  end
@@ -9,14 +9,13 @@ module PgEventstore
9
9
 
10
10
  # @return [Array<Hash<String => String>>]
11
11
  def collection
12
- @_collection ||=
12
+ @collection ||=
13
13
  begin
14
- sql_builder =
15
- SQLBuilder.new.select('context').from('partitions').
16
- where('stream_name is null and event_type is null').
17
- limit(per_page).order("context #{order}")
14
+ sql_builder = SQLBuilder.new.select('context').from('partitions')
15
+ sql_builder.where('stream_name is null and event_type is null')
18
16
  sql_builder.where("context #{direction_operator} ?", starting_id) if starting_id
19
17
  sql_builder.where('context ilike ?', "%#{options[:query]}%")
18
+ sql_builder.limit(per_page).order("context #{order}")
20
19
  connection.with do |conn|
21
20
  conn.exec_params(*sql_builder.to_exec_params)
22
21
  end.to_a
@@ -28,10 +27,11 @@ module PgEventstore
28
27
  return unless collection.size == per_page
29
28
 
30
29
  starting_id = collection.first['context']
31
- sql_builder =
32
- SQLBuilder.new.select('context').from('partitions').where('stream_name is null and event_type is null').
33
- where("context #{direction_operator} ?", starting_id).where('context ilike ?', "%#{options[:query]}%").
34
- limit(1).offset(per_page).order("context #{order}")
30
+ sql_builder = SQLBuilder.new.select('context').from('partitions')
31
+ sql_builder.where('stream_name is null and event_type is null')
32
+ sql_builder.where("context #{direction_operator} ?", starting_id)
33
+ sql_builder.where('context ilike ?', "%#{options[:query]}%")
34
+ sql_builder.limit(1).offset(per_page).order("context #{order}")
35
35
 
36
36
  connection.with do |conn|
37
37
  conn.exec_params(*sql_builder.to_exec_params)
@@ -9,12 +9,11 @@ module PgEventstore
9
9
 
10
10
  # @return [Array<Hash<String => String>>]
11
11
  def collection
12
- @_collection ||=
12
+ @collection ||=
13
13
  begin
14
- sql_builder =
15
- SQLBuilder.new.select('stream_id').from('events').
16
- where('context = ? and stream_name = ?', options[:context], options[:stream_name]).
17
- where('stream_id like ?', "#{options[:query]}%")
14
+ sql_builder = SQLBuilder.new.select('stream_id').from('events')
15
+ sql_builder.where('context = ? and stream_name = ?', options[:context], options[:stream_name])
16
+ sql_builder.where('stream_id like ?', "#{options[:query]}%")
18
17
  sql_builder.where("stream_id #{direction_operator} ?", starting_id) if starting_id
19
18
  sql_builder.group('stream_id').limit(per_page).order("stream_id #{order}")
20
19
  connection.with do |conn|
@@ -28,11 +27,11 @@ module PgEventstore
28
27
  return unless collection.size == per_page
29
28
 
30
29
  starting_id = collection.first['stream_id']
31
- sql_builder =
32
- SQLBuilder.new.select('stream_id').from('events').
33
- where("stream_id #{direction_operator} ?", starting_id).where('stream_id like ?', "#{options[:query]}%").
34
- where('context = ? and stream_name = ?', options[:context], options[:stream_name]).
35
- group('stream_id').limit(1).offset(per_page).order("stream_id #{order}")
30
+ sql_builder = SQLBuilder.new.select('stream_id').from('events')
31
+ sql_builder.where("stream_id #{direction_operator} ?", starting_id)
32
+ sql_builder.where('stream_id like ?', "#{options[:query]}%")
33
+ sql_builder.where('context = ? and stream_name = ?', options[:context], options[:stream_name])
34
+ sql_builder.group('stream_id').limit(1).offset(per_page).order("stream_id #{order}")
36
35
 
37
36
  connection.with do |conn|
38
37
  conn.exec_params(*sql_builder.to_exec_params)