Module: MatViews::Tasks::Helpers

Defined in:
lib/tasks/helpers.rb

Overview

Helpers module provides utility methods for MatViews Rake tasks.

These helpers support:

  • Database connections

  • Logging

  • Parsing boolean/flag-like arguments

  • Confirmation prompts

  • Enqueueing background jobs for create, refresh, and delete operations

  • Looking up materialised view definitions

By extracting this logic, Rake tasks can remain clean and declarative.

Class Method Summary collapse

Class Method Details

.booleanish_true?(value) ⇒ Boolean

Check if a value is a “truthy” boolean-like string. Recognized: 1, true, yes, y, –yes

Parameters:

  • value (String, Boolean, nil)

Returns:

  • (Boolean)


38
39
40
41
# File 'lib/tasks/helpers.rb', line 38

def booleanish_true?(value)
  str = value.to_s.strip.downcase
  %w[1 true yes y --yes].include?(str)
end

.confirm!(message, skip: false) ⇒ void

This method returns an undefined value.

Ask user to confirm a destructive action, unless skipped.

If ‘skip` is true, logs the message and returns without prompting. Otherwise, prompts user for confirmation and raises if declined.

Parameters:

  • message (String)

    confirmation message

  • skip (Boolean) (defaults to: false)

    whether to skip confirmation

Raises:

  • (RuntimeError)

    if user declines confirmation



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/tasks/helpers.rb', line 111

def confirm!(message, skip: false)
  if skip
    logger.info("[mat_views] #{message} - confirmation skipped.")
    return
  end

  logger.info("[mat_views] #{message}")
  $stdout.print('Proceed? [y/N]: ')
  $stdout.flush
  ans = $stdin.gets&.strip&.downcase
  return if ans&.start_with?('y')

  raise 'Aborted.'
end

.enqueue_create(mat_view_definition_id, force, row_count_strategy) ⇒ void

This method returns an undefined value.

Enqueue a CreateView job for given definition.

Parameters:

  • mat_view_definition_id (Integer)

    MatViewDefinition ID

  • force (Boolean)

    whether to force creation

  • row_count_strategy (Symbol)

    :estimated or :exact or :none



132
133
134
135
136
137
138
# File 'lib/tasks/helpers.rb', line 132

def enqueue_create(mat_view_definition_id, force, row_count_strategy)
  MatViews::Jobs::Adapter.enqueue(
    MatViews::CreateViewJob,
    queue: MatViews.configuration.job_queue || :default,
    args: [mat_view_definition_id, force, row_count_strategy]
  )
end

.enqueue_delete(mat_view_definition_id, cascade, row_count_strategy) ⇒ void

This method returns an undefined value.

Enqueue a DeleteView job for given definition.

This method schedules a job to delete the materialised view, optionally with CASCADE. It uses the configured job adapter to enqueue the job.

Parameters:

  • mat_view_definition_id (Integer)

    MatViewDefinition ID

  • cascade (Boolean)

    whether to drop with CASCADE

  • row_count_strategy (Symbol)

    :estimated or :exact or :none



176
177
178
179
180
181
182
# File 'lib/tasks/helpers.rb', line 176

def enqueue_delete(mat_view_definition_id, cascade, row_count_strategy)
  MatViews::Jobs::Adapter.enqueue(
    MatViews::DeleteViewJob,
    queue: MatViews.configuration.job_queue || :default,
    args: [mat_view_definition_id, cascade, row_count_strategy]
  )
end

.enqueue_refresh(mat_view_definition_id, row_count_strategy) ⇒ void

This method returns an undefined value.

Enqueue a RefreshView job for given definition.

This method allows scheduling a refresh operation with the specified row count strategy. It uses the configured job adapter to enqueue the job.

Parameters:

  • mat_view_definition_id (Integer)

    MatViewDefinition ID

  • row_count_strategy (Symbol)

    :estimated or :exact



148
149
150
151
152
153
154
# File 'lib/tasks/helpers.rb', line 148

def enqueue_refresh(mat_view_definition_id, row_count_strategy)
  MatViews::Jobs::Adapter.enqueue(
    MatViews::RefreshViewJob,
    queue: MatViews.configuration.job_queue || :default,
    args: [mat_view_definition_id, row_count_strategy]
  )
end

.find_definition_by_name!(raw_name) ⇒ MatViews::MatViewDefinition

Find a MatViewDefinition by raw name (schema.rel or rel). Raises if none found or mismatch with DB presence.

Parameters:

  • raw_name (String)

    schema-qualified or unqualified view name

Returns:

Raises:

  • (RuntimeError)

    if no definition found or mismatch with DB



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/tasks/helpers.rb', line 80

def find_definition_by_name!(raw_name)
  raw_name_string = raw_name&.to_s&.strip
  raise 'view_name is required' unless raw_name_string && !raw_name_string.empty?

  schema, rel =
    if raw_name_string.include?('.')
      parts = raw_name_string.split('.', 2)
      [parts[0], parts[1]]
    else
      [nil, raw_name_string]
    end

  defn = MatViews::MatViewDefinition.find_by(name: rel)
  return defn if defn

  if schema && matview_exists?(rel, schema: schema)
    raise "Materialized view #{schema}.#{rel} exists, but no MatViews::MatViewDefinition record was found for name=#{rel.inspect}"
  end

  raise "No MatViews::MatViewDefinition found for #{raw_name.inspect}"
end

.loggerLogger

Returns the Rails logger.

Returns:

  • (Logger)


30
31
32
# File 'lib/tasks/helpers.rb', line 30

def logger
  Rails.logger
end

.matview_exists?(rel, schema: 'public') ⇒ Boolean

Check if a materialised view exists in schema.

Parameters:

  • rel (String)

    relation name

  • schema (String) (defaults to: 'public')

    schema name

Returns:

  • (Boolean)


66
67
68
69
70
71
72
# File 'lib/tasks/helpers.rb', line 66

def matview_exists?(rel, schema: 'public')
  mv_conn.select_value(<<~SQL).to_i.positive?
    SELECT COUNT(*)
    FROM pg_matviews
    WHERE schemaname = #{mv_conn.quote(schema)} AND matviewname = #{mv_conn.quote(rel)}
  SQL
end

.mv_connActiveRecord::ConnectionAdapters::AbstractAdapter

Returns the current database connection.

Returns:

  • (ActiveRecord::ConnectionAdapters::AbstractAdapter)


24
25
26
# File 'lib/tasks/helpers.rb', line 24

def mv_conn
  ActiveRecord::Base.connection
end

.parse_cascade?(arg) ⇒ Boolean

Parse cascade option (CASCADE env or arg).

This method checks if the CASCADE option is set to true, allowing for cascading drops. It defaults to the value of the CASCADE environment variable if not provided.

Parameters:

  • arg (String, Boolean, nil)

    argument or environment variable value

Returns:

  • (Boolean)

    true if cascade is enabled, false otherwise



163
164
165
# File 'lib/tasks/helpers.rb', line 163

def parse_cascade?(arg)
  booleanish_true?(arg || ENV.fetch('CASCADE', nil))
end

.parse_force?(arg) ⇒ Boolean

Parse whether force mode is enabled (FORCE env or arg).

Returns:

  • (Boolean)


49
50
51
# File 'lib/tasks/helpers.rb', line 49

def parse_force?(arg)
  booleanish_true?(arg || ENV.fetch('FORCE', nil))
end

.parse_row_count_strategy(arg) ⇒ Object

Parse row count strategy from arg or ROW_COUNT_STRATEGY env. Defaults to :none if blank.



55
56
57
58
59
60
# File 'lib/tasks/helpers.rb', line 55

def parse_row_count_strategy(arg)
  str = (arg || ENV.fetch('ROW_COUNT_STRATEGY', nil)).to_s.strip
  return :none if str.empty?

  str.to_sym
end

.skip_confirm?(arg) ⇒ Boolean

Whether confirmation should be skipped (YES env or arg).

Returns:

  • (Boolean)


44
45
46
# File 'lib/tasks/helpers.rb', line 44

def skip_confirm?(arg)
  booleanish_true?(arg || ENV.fetch('YES', nil))
end