Class: OnlineMigrations::BackgroundDataMigrations::BackfillColumn

Inherits:
DataMigration
  • Object
show all
Defined in:
lib/online_migrations/background_data_migrations/backfill_column.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from DataMigration

#after_cancel, #after_complete, #after_pause, #after_resume, #after_start, #after_stop, #around_process, #build_enumerator, collection_batch_size, named

Constructor Details

#initialize(table_name, updates, model_name = nil) ⇒ BackfillColumn

Returns a new instance of BackfillColumn.



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 9

def initialize(table_name, updates, model_name = nil)
  @table_name = table_name
  @updates = updates

  @model =
    if model_name
      Object.const_get(model_name, false)
    else
      Utils.define_model(table_name)
    end
end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



7
8
9
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 7

def model
  @model
end

#table_nameObject (readonly)

Returns the value of attribute table_name.



7
8
9
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 7

def table_name
  @table_name
end

#updatesObject (readonly)

Returns the value of attribute updates.



7
8
9
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 7

def updates
  @updates
end

Instance Method Details

#collectionObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 21

def collection
  column, value = updates.first

  relation =
    if updates.size == 1 && !value.nil?
      # If value is nil, the generated SQL is correct (`WHERE column IS NOT NULL`).
      # Otherwise, the SQL is `WHERE column != value`. This condition ignores column
      # with NULLs in it, so we need to also manually check for NULLs.
      arel_column = model.arel_table[column]
      model.unscoped.where(arel_column.not_eq(value).or(arel_column.eq(nil)))
    else
      model.unscoped.where.not(updates)
    end

  relation.in_batches(of: 100, use_ranges: true)
end

#countObject



42
43
44
45
46
47
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 42

def count
  # Exact counts are expensive on large tables, since PostgreSQL
  # needs to do a full scan. An estimated count should give a pretty decent
  # approximation of rows count in this case.
  Utils.estimated_count(model.connection, table_name)
end

#process(relation) ⇒ Object



38
39
40
# File 'lib/online_migrations/background_data_migrations/backfill_column.rb', line 38

def process(relation)
  relation.update_all(updates)
end