Module: Gitlab::Database::BulkUpdate

Defined in:
lib/gitlab/database/bulk_update.rb

Overview

Constructs queries of the form:

with cte(a, b, c) as (
  select * from (values (:x, :y, :z), (:q, :r, :s)) as t
  )
update table set b = cte.b, c = cte.c where a = cte.a

Which is useful if you want to update a set of records in a single query but cannot express the update as a calculation (i.e. you have arbitrary updates to perform).

The requirements are that the table must have an ID column used to identify the rows to be updated.

Usage:

mapping = {
  issue_a => { title: 'This title', relative_position: 100 },
  issue_b => { title: 'That title', relative_position: 173 }
}

::Gitlab::Database::BulkUpdate.execute(i[title relative_position], mapping)

Note that this is a very low level tool, and operates on the raw column values. Enums/state fields must be translated into their underlying representations, for example, and no hooks will be called.

Defined Under Namespace

Classes: Setter

Constant Summary collapse

LIST_SEPARATOR =
', '

Class Method Summary collapse

Class Method Details

.execute(columns, mapping, &to_class) ⇒ Object

Raises:

  • (ArgumentError)


141
142
143
144
145
146
147
148
149
# File 'lib/gitlab/database/bulk_update.rb', line 141

def self.execute(columns, mapping, &to_class)
  raise ArgumentError if mapping.blank?

  entries_by_class = mapping.group_by { |k, v| to_class ? yield(k) : k.class }

  entries_by_class.each do |model, entries|
    Setter.new(model, columns, entries).update!
  end
end