diff --git a/lib/gitlab/cycle_analytics/events_fetcher.rb b/lib/gitlab/cycle_analytics/events_fetcher.rb index 9e62eef706c1f16fa825e129af6a8e064180fe21..ceed5823371afb73edff4f231301a25f31cac275 100644 --- a/lib/gitlab/cycle_analytics/events_fetcher.rb +++ b/lib/gitlab/cycle_analytics/events_fetcher.rb @@ -11,14 +11,21 @@ module Gitlab def fetch_issues cte_table = Arel::Table.new("cte_table_for_issue") - interval_query = Arel::Nodes::As.new( - cte_table, - subtract_datetimes(base_query_for(:issue), *attributes, 'issue')) + # Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time). + # Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time). + # We compute the (end_time - start_time) interval, and give it an alias based on the current + # cycle analytics stage. - #TODO ActiveRecord::Base.connection.execute(interval_query) + base_query = base_query_for(:issue) + + diff_fn = subtract_datetimes_diff(base_query, issue_table[:created_at], metric_attributes) + + query = base_query.project(diff_fn.as('issue_diff')) + + ActiveRecord::Base.connection.execute(query.to_sql) end - def attributes + def metric_attributes [issue_metrics_table[:first_associated_with_milestone_at], issue_metrics_table[:first_added_to_board_at]] end diff --git a/lib/gitlab/cycle_analytics/metrics_fetcher.rb b/lib/gitlab/cycle_analytics/metrics_fetcher.rb index 51b4963cf088dcc56376c281665f315c8f870251..97b55656d7961f12e7b85399f91b7ed4bab55ab8 100644 --- a/lib/gitlab/cycle_analytics/metrics_fetcher.rb +++ b/lib/gitlab/cycle_analytics/metrics_fetcher.rb @@ -28,7 +28,7 @@ module Gitlab # automatically excluded. def base_query_for(name) # Load issues - query = issue_metrics_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])). + query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])). join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])). where(issue_table[:project_id].eq(@project.id)). where(issue_table[:deleted_at].eq(nil)). diff --git a/lib/gitlab/database/date_time.rb b/lib/gitlab/database/date_time.rb index b6a89f715fdaaa725a5546682d165c2beac28128..e2524886de225b67c59c2df1d6827fde640e0dd0 100644 --- a/lib/gitlab/database/date_time.rb +++ b/lib/gitlab/database/date_time.rb @@ -8,20 +8,24 @@ module Gitlab # Note: For MySQL, the interval is returned in seconds. # For PostgreSQL, the interval is returned as an INTERVAL type. def subtract_datetimes(query_so_far, end_time_attrs, start_time_attrs, as) - diff_fn = if Gitlab::Database.postgresql? - Arel::Nodes::Subtraction.new( - Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs)), - Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs))) - elsif Gitlab::Database.mysql? - Arel::Nodes::NamedFunction.new( - "TIMESTAMPDIFF", - [Arel.sql('second'), - Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs)), - Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs))]) - end + diff_fn = subtract_datetimes_diff(query_so_far, end_time_attrs, start_time_attrs) query_so_far.project(diff_fn.as(as)) end + + def subtract_datetimes_diff(query_so_far, end_time_attrs, start_time_attrs) + if Gitlab::Database.postgresql? + Arel::Nodes::Subtraction.new( + Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs)), + Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs))) + elsif Gitlab::Database.mysql? + Arel::Nodes::NamedFunction.new( + "TIMESTAMPDIFF", + [Arel.sql('second'), + Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs)), + Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs))]) + end + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb index b68cc16f4e64d51f3f3ce4f732cd8c87f5fd349b..64387ef10d3619a3776dae394cd4d906b7275f3b 100644 --- a/spec/lib/gitlab/cycle_analytics/events_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb @@ -15,12 +15,13 @@ describe Gitlab::CycleAnalytics::Events do let!(:context) { create(:issue, project: project) } xit 'does something' do - expect(subject.issue_events).to eq([]) + expect(subject.issue_events).to eq([context]) end end def setup(context) - create(:milestone, project: project) + milestone = create(:milestone, project: project) + context.update(milestone: milestone) create_merge_request_closing_issue(context) end end