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 @@
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 self.execute(epic_id)
results = 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)
new(results)
def initialize(epic_id)
@epic_id = epic_id
end
def initialize(results)
@results = results
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
......@@ -45,16 +47,16 @@ module Epics
private
attr_reader :results
attr_reader :epic_id
def start_date_sourcing_milestone
@start_date_sourcing_milestone ||= results
@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 ||= results
@due_date_sourcing_milestone ||= execute
.reject { |row| row[DUE_DATE_INDEX].nil? }
.max_by { |row| row[DUE_DATE_INDEX] }
end
......
......@@ -93,7 +93,7 @@ module EE
groups.each do |milestone_ids, epics|
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(
[
......@@ -143,7 +143,7 @@ module EE
alias_attribute(:due_date, :end_date)
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_sourcing_milestone_id = results.start_date_sourcing_milestone_id
......
......@@ -25,7 +25,7 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
groups.each do |milestone_ids, epics|
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(
[
......@@ -45,6 +45,69 @@ class UpdateEpicDatesFromMilestones < ActiveRecord::Migration
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
# 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.
......
......@@ -13,7 +13,7 @@ describe Epics::DateSourcingMilestonesFinder do
create(:issue, epic: epic, milestone: milestone2)
create(:issue, epic: epic, milestone: milestone3)
results = described_class.execute(epic.id)
results = described_class.new(epic.id)
expect(results).to have_attributes(
start_date: milestone1.start_date,
......@@ -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))
create(:issue, epic: epic, milestone: milestone1)
results = described_class.execute(epic.id)
results = described_class.new(epic.id)
expect(results).to have_attributes(
start_date: milestone1.start_date,
......@@ -43,7 +43,7 @@ describe Epics::DateSourcingMilestonesFinder do
milestone1 = create(:milestone, start_date: Date.new(2000, 1, 1))
create(:issue, epic: epic, milestone: milestone1)
results = described_class.execute(epic.id)
results = described_class.new(epic.id)
expect(results).to have_attributes(
start_date: milestone1.start_date,
......@@ -56,7 +56,7 @@ describe Epics::DateSourcingMilestonesFinder do
it 'handles epics without milestone' do
epic = create(:epic)
results = described_class.execute(epic.id)
results = described_class.new(epic.id)
expect(results).to have_attributes(
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