Commit 74bdc9a3 authored by Mark Chao's avatar Mark Chao

Use DateSourcingMilestonesFinder in migration

parent 38b34c87
......@@ -14,7 +14,7 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
has_many :epic_issues
has_many :issues, through: :epic_issues
def self.update_dates(epics)
def self.update_start_and_due_dates(epics)
groups = epics.includes(:issues).group_by do |epic|
milestone_ids = epic.issues.map(&:milestone_id)
milestone_ids.compact!
......@@ -25,62 +25,29 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
groups.each do |milestone_ids, epics|
next if milestone_ids.empty?
data = epics.first.fetch_milestone_date_data
data = ::Epics::DateSourcingMilestonesFinder.execute(epics.first.id)
self.where(id: epics.map(&:id)).update_all(
[
%{
start_date = CASE WHEN start_date_is_fixed = true THEN start_date ELSE ? END,
start_date_sourcing_milestone_id = ?,
end_date = CASE WHEN due_date_is_fixed = true THEN end_date ELSE ? END,
due_date_sourcing_milestone_id = ?
},
data[:start_date],
data[:start_date_sourcing_milestone_id],
data[:due_date],
data[:due_date_sourcing_milestone_id]
start_date = CASE WHEN start_date_is_fixed = true THEN start_date ELSE ? END,
start_date_sourcing_milestone_id = ?,
end_date = CASE WHEN due_date_is_fixed = true THEN end_date ELSE ? END,
due_date_sourcing_milestone_id = ?
},
data.start_date,
data.start_date_sourcing_milestone_id,
data.due_date,
data.due_date_sourcing_milestone_id
]
)
end
end
def fetch_milestone_date_data
sql = <<~SQL
SELECT milestones.id, milestones.start_date, milestones.due_date FROM milestones
INNER JOIN issues ON issues.milestone_id = milestones.id
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id
INNER JOIN (
SELECT MIN(milestones.start_date) AS start_date, MAX(milestones.due_date) AS due_date
FROM milestones
INNER JOIN issues ON issues.milestone_id = milestones.id
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id
WHERE epic_issues.epic_id = #{id}
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
WHERE epic_issues.epic_id = #{id}
SQL
db_results = ActiveRecord::Base.connection.select_all(sql).to_a
results = {}
db_results
.reject { |row| row['start_date'].nil? }
.min_by { |row| row['start_date'] }&.tap do |row|
results[:start_date] = row['start_date']
results[:start_date_sourcing_milestone_id] = row['id']
end
db_results
.reject { |row| row['due_date'].nil? }
.max_by { |row| row['due_date'] }&.tap do |row|
results[:due_date] = row['due_date']
results[:due_date_sourcing_milestone_id] = row['id']
end
results
end
end
def up
Epic.joins(:issues).where('issues.milestone_id IS NOT NULL').each_batch do |epics|
Epic.update_dates(epics)
Epic.update_start_and_due_dates(epics)
end
end
......
require 'spec_helper'
require Rails.root.join('ee', 'db', 'post_migrate', '20180713171825_update_epic_dates_from_milestones.rb')
describe UpdateEpicDatesFromMilestones, :migration do
let(:migration) { described_class.new }
let(:users) { table(:users) }
let(:namespaces) { table(:namespaces) }
let(:epics) { table(:epics) }
let(:projects) { table(:projects) }
let(:issues) { table(:issues) }
let(:epic_issues) { table(:epic_issues) }
let(:milestones) { table(:milestones) }
describe '#up' do
before do
user = users.create!(email: 'test@example.com', projects_limit: 100, username: 'test')
namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org')
projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', path: 'gitlab1')
epics.create!(id: 1, iid: 1, group_id: 1, title: 'epic with start and due dates', title_html: '', author_id: user.id)
epics.create!(id: 2, iid: 2, group_id: 1, title: 'epic with only due date', title_html: '', author_id: user.id)
epics.create!(id: 3, iid: 3, group_id: 1, title: 'epic without milestone', title_html: '', author_id: user.id)
milestones.create!(
id: 1,
iid: 1,
project_id: 1,
title: 'milestone-1',
start_date: Date.new(2000, 1, 1),
due_date: Date.new(2000, 1, 10)
)
milestones.create!(
id: 2,
iid: 2,
project_id: 1,
title: 'milestone-2',
due_date: Date.new(2000, 1, 30)
)
issues.create!(id: 1, iid: 1, project_id: 1, milestone_id: 1, title: 'issue-1')
issues.create!(id: 2, iid: 2, project_id: 1, milestone_id: 2, title: 'issue-2')
issues.create!(id: 3, iid: 3, project_id: 1, milestone_id: 2, title: 'issue-2')
epic_issues.create!(epic_id: 1, issue_id: 1)
epic_issues.create!(epic_id: 1, issue_id: 2)
epic_issues.create!(epic_id: 2, issue_id: 3)
end
it 'updates dates milestone ids' do
migration.up
expect(Epic.find(1)).to have_attributes(
start_date: Date.new(2000, 1, 1),
start_date_sourcing_milestone_id: 1,
due_date: Date.new(2000, 1, 30),
due_date_sourcing_milestone_id: 2
)
expect(Epic.find(2)).to have_attributes(
start_date: nil,
start_date_sourcing_milestone_id: nil,
due_date: Date.new(2000, 1, 30),
due_date_sourcing_milestone_id: 2
)
expect(Epic.find(3)).to have_attributes(
start_date: nil,
start_date_sourcing_milestone_id: nil,
due_date: nil,
due_date_sourcing_milestone_id: nil
)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment