diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb index b62eb50840d..7f559f0a7ed 100644 --- a/app/models/concerns/relative_positioning.rb +++ b/app/models/concerns/relative_positioning.rb @@ -102,33 +102,16 @@ module RelativePositioning delta = at_end ? gap : -gap indexed = (at_end ? objects : objects.reverse).each_with_index - # Some classes are polymorphic, and not all siblings are in the same table. - by_model = indexed.group_by { |pair| pair.first.class } lower_bound, upper_bound = at_end ? [position, MAX_POSITION] : [MIN_POSITION, position] - by_model.each do |model, pairs| - model.transaction do - pairs.each_slice(100) do |batch| - # These are known to be integers, one from the DB, and the other - # calculated by us, and thus safe to interpolate - values = batch.map do |obj, i| - desired_pos = position + delta * (i + 1) - pos = desired_pos.clamp(lower_bound, upper_bound) - obj.relative_position = pos - "(#{obj.id}, #{pos})" - end.join(', ') - - model.connection.exec_query(<<~SQL, "UPDATE #{model.table_name} positions") - WITH cte(cte_id, new_pos) AS ( - SELECT * - FROM (VALUES #{values}) as t (id, pos) - ) - UPDATE #{model.table_name} - SET relative_position = cte.new_pos - FROM cte - WHERE cte_id = id - SQL + representative.model_class.transaction do + indexed.each_slice(100) do |batch| + mapping = batch.to_h.transform_values! do |i| + desired_pos = position + delta * (i + 1) + { relative_position: desired_pos.clamp(lower_bound, upper_bound) } end + + ::Gitlab::Database::BulkUpdate.execute([:relative_position], mapping, &:model_class) end end @@ -206,4 +189,10 @@ module RelativePositioning def reset_relative_position reset.relative_position end + + # Override if the model class needs a more complicated computation (e.g. the + # object is a member of a union). + def model_class + self.class + end end diff --git a/danger/pajamas/Dangerfile b/danger/pajamas/Dangerfile index d60582b0bc9..744fa902817 100644 --- a/danger/pajamas/Dangerfile +++ b/danger/pajamas/Dangerfile @@ -2,15 +2,39 @@ # rubocop:disable Style/SignalException PATTERNS = %w[ + %a.btn.btn- + %button.btn.btn- + .alert + .alert-danger + .alert-dismissible + .alert-info + .alert-link + .alert-primary + .alert-success + .alert-warning + .nav-tabs + .toolbar-button-icon + .tooltip + .tooltip-inner +