Commit 657712a9 authored by Mark Chao's avatar Mark Chao

Change DateSourcingMilestonesFinder to be similar to other finderd

Embed DateSourcingMilestoneFinder into migration
parent 681dd0da
...@@ -2,29 +2,31 @@ ...@@ -2,29 +2,31 @@
module Epics module Epics
class DateSourcingMilestonesFinder class DateSourcingMilestonesFinder
include Gitlab::Utils::StrongMemoize
FIELDS = [:id, :start_date, :due_date].freeze FIELDS = [:id, :start_date, :due_date].freeze
ID_INDEX = FIELDS.index(:id) ID_INDEX = FIELDS.index(:id)
START_DATE_INDEX = FIELDS.index(:start_date) START_DATE_INDEX = FIELDS.index(:start_date)
DUE_DATE_INDEX = FIELDS.index(:due_date) DUE_DATE_INDEX = FIELDS.index(:due_date)
def self.execute(epic_id) def initialize(epic_id)
results = Milestone.joins(issues: :epic_issue).where(epic_issues: { epic_id: epic_id }).joins( @epic_id = epic_id
<<~SQL
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 = #{epic_id}
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
SQL
).pluck(*FIELDS)
new(results)
end end
def initialize(results) def execute
@results = results strong_memoize(:execute) do
Milestone.joins(issues: :epic_issue).where(epic_issues: { epic_id: epic_id }).joins(
<<~SQL
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 = #{epic_id}
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
SQL
).pluck(*FIELDS)
end
end end
def start_date def start_date
...@@ -45,16 +47,16 @@ module Epics ...@@ -45,16 +47,16 @@ module Epics
private private
attr_reader :results attr_reader :epic_id
def start_date_sourcing_milestone def start_date_sourcing_milestone
@start_date_sourcing_milestone ||= results @start_date_sourcing_milestone ||= execute
.reject { |row| row[START_DATE_INDEX].nil? } .reject { |row| row[START_DATE_INDEX].nil? }
.min_by { |row| row[START_DATE_INDEX] } .min_by { |row| row[START_DATE_INDEX] }
end end
def due_date_sourcing_milestone def due_date_sourcing_milestone
@due_date_sourcing_milestone ||= results @due_date_sourcing_milestone ||= execute
.reject { |row| row[DUE_DATE_INDEX].nil? } .reject { |row| row[DUE_DATE_INDEX].nil? }
.max_by { |row| row[DUE_DATE_INDEX] } .max_by { |row| row[DUE_DATE_INDEX] }
end end
......
...@@ -93,7 +93,7 @@ module EE ...@@ -93,7 +93,7 @@ module EE
groups.each do |milestone_ids, epics| groups.each do |milestone_ids, epics|
next if milestone_ids.empty? next if milestone_ids.empty?
results = Epics::DateSourcingMilestonesFinder.execute(epics.first.id) results = Epics::DateSourcingMilestonesFinder.new(epics.first.id)
self.where(id: epics.map(&:id)).update_all( self.where(id: epics.map(&:id)).update_all(
[ [
...@@ -143,7 +143,7 @@ module EE ...@@ -143,7 +143,7 @@ module EE
alias_attribute(:due_date, :end_date) alias_attribute(:due_date, :end_date)
def update_start_and_due_dates def update_start_and_due_dates
results = Epics::DateSourcingMilestonesFinder.execute(id) results = Epics::DateSourcingMilestonesFinder.new(id)
self.start_date = start_date_is_fixed? ? start_date_fixed : results.start_date self.start_date = start_date_is_fixed? ? start_date_fixed : results.start_date
self.start_date_sourcing_milestone_id = results.start_date_sourcing_milestone_id self.start_date_sourcing_milestone_id = results.start_date_sourcing_milestone_id
......
...@@ -25,7 +25,7 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration ...@@ -25,7 +25,7 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
groups.each do |milestone_ids, epics| groups.each do |milestone_ids, epics|
next if milestone_ids.empty? next if milestone_ids.empty?
data = ::Epics::DateSourcingMilestonesFinder.execute(epics.first.id) data = ::UpdateEpicDatesFromMilestones::Epics::DateSourcingMilestonesFinder.new(epics.first.id)
self.where(id: epics.map(&:id)).update_all( self.where(id: epics.map(&:id)).update_all(
[ [
...@@ -45,6 +45,69 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration ...@@ -45,6 +45,69 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
end end
end end
module Epics
class DateSourcingMilestonesFinder
include Gitlab::Utils::StrongMemoize
FIELDS = [:id, :start_date, :due_date].freeze
ID_INDEX = FIELDS.index(:id)
START_DATE_INDEX = FIELDS.index(:start_date)
DUE_DATE_INDEX = FIELDS.index(:due_date)
def initialize(epic_id)
@epic_id = epic_id
end
def execute
strong_memoize(:execute) do
Milestone.joins(issues: :epic_issue).where(epic_issues: { epic_id: epic_id }).joins(
<<~SQL
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 = #{epic_id}
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
SQL
).pluck(*FIELDS)
end
end
def start_date
start_date_sourcing_milestone&.slice(START_DATE_INDEX)
end
def start_date_sourcing_milestone_id
start_date_sourcing_milestone&.slice(ID_INDEX)
end
def due_date
due_date_sourcing_milestone&.slice(DUE_DATE_INDEX)
end
def due_date_sourcing_milestone_id
due_date_sourcing_milestone&.slice(ID_INDEX)
end
private
attr_reader :epic_id
def start_date_sourcing_milestone
@start_date_sourcing_milestone ||= execute
.reject { |row| row[START_DATE_INDEX].nil? }
.min_by { |row| row[START_DATE_INDEX] }
end
def due_date_sourcing_milestone
@due_date_sourcing_milestone ||= execute
.reject { |row| row[DUE_DATE_INDEX].nil? }
.max_by { |row| row[DUE_DATE_INDEX] }
end
end
end
def up def up
# Fill fixed date columns for remaining eligible records touched after regular migration is run # Fill fixed date columns for remaining eligible records touched after regular migration is run
# (20180711014026_update_date_columns_on_epics) but before new app code takes effect. # (20180711014026_update_date_columns_on_epics) but before new app code takes effect.
......
...@@ -13,7 +13,7 @@ describe Epics::DateSourcingMilestonesFinder do ...@@ -13,7 +13,7 @@ describe Epics::DateSourcingMilestonesFinder do
create(:issue, epic: epic, milestone: milestone2) create(:issue, epic: epic, milestone: milestone2)
create(:issue, epic: epic, milestone: milestone3) create(:issue, epic: epic, milestone: milestone3)
results = described_class.execute(epic.id) results = described_class.new(epic.id)
expect(results).to have_attributes( expect(results).to have_attributes(
start_date: milestone1.start_date, start_date: milestone1.start_date,
...@@ -28,7 +28,7 @@ describe Epics::DateSourcingMilestonesFinder do ...@@ -28,7 +28,7 @@ describe Epics::DateSourcingMilestonesFinder do
milestone1 = create(:milestone, start_date: Date.new(2000, 1, 1), due_date: Date.new(2000, 1, 10)) milestone1 = create(:milestone, start_date: Date.new(2000, 1, 1), due_date: Date.new(2000, 1, 10))
create(:issue, epic: epic, milestone: milestone1) create(:issue, epic: epic, milestone: milestone1)
results = described_class.execute(epic.id) results = described_class.new(epic.id)
expect(results).to have_attributes( expect(results).to have_attributes(
start_date: milestone1.start_date, start_date: milestone1.start_date,
...@@ -43,7 +43,7 @@ describe Epics::DateSourcingMilestonesFinder do ...@@ -43,7 +43,7 @@ describe Epics::DateSourcingMilestonesFinder do
milestone1 = create(:milestone, start_date: Date.new(2000, 1, 1)) milestone1 = create(:milestone, start_date: Date.new(2000, 1, 1))
create(:issue, epic: epic, milestone: milestone1) create(:issue, epic: epic, milestone: milestone1)
results = described_class.execute(epic.id) results = described_class.new(epic.id)
expect(results).to have_attributes( expect(results).to have_attributes(
start_date: milestone1.start_date, start_date: milestone1.start_date,
...@@ -56,7 +56,7 @@ describe Epics::DateSourcingMilestonesFinder do ...@@ -56,7 +56,7 @@ describe Epics::DateSourcingMilestonesFinder do
it 'handles epics without milestone' do it 'handles epics without milestone' do
epic = create(:epic) epic = create(:epic)
results = described_class.execute(epic.id) results = described_class.new(epic.id)
expect(results).to have_attributes( expect(results).to have_attributes(
start_date: nil, start_date: nil,
......
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