diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-12 09:08:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-12 09:08:53 +0300 |
commit | a1e664d4cc1edc8e5d6bd4a838e5e6a7426cc0f6 (patch) | |
tree | 4d687e4149c7cbd2b3d01cdca370bd6aa9c7549f /app/models/concerns/relative_positioning.rb | |
parent | db4ee69eb3df58ac9f109d64228d1468e4ff7962 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/concerns/relative_positioning.rb')
-rw-r--r-- | app/models/concerns/relative_positioning.rb | 37 |
1 files changed, 13 insertions, 24 deletions
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 |