Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/release.rb')
-rw-r--r--app/models/release.rb38
1 files changed, 36 insertions, 2 deletions
diff --git a/app/models/release.rb b/app/models/release.rb
index 0f00732b62e..7f74872cf67 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -35,8 +35,10 @@ class Release < ApplicationRecord
scope :sorted, -> { order(released_at: :desc) }
scope :preloaded, -> {
- includes(:author, :evidences, :milestones, :links, :sorted_links,
- project: [:project_feature, :route, { namespace: :route }])
+ includes(
+ :author, :evidences, :milestones, :links, :sorted_links,
+ project: [:project_feature, :route, { namespace: :route }]
+ )
}
scope :with_milestones, -> { joins(:milestone_releases) }
scope :with_group_milestones, -> { joins(:milestones).where.not(milestones: { group_id: nil }) }
@@ -54,6 +56,38 @@ class Release < ApplicationRecord
MAX_NUMBER_TO_DISPLAY = 3
+ class << self
+ # In the future, we should support `order_by=semver`;
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/352945
+ def latest(order_by: 'released_at')
+ sort_by_attribute("#{order_by}_desc").first
+ end
+
+ # This query uses LATERAL JOIN to find the latest release for each project. To avoid
+ # joining the `releases` table, we build an in-memory table using the project ids.
+ # Example:
+ # SELECT ...
+ # FROM (VALUES (PROJECT_ID_1),(PROJECT_ID_2)) project_ids (id)
+ # INNER JOIN LATERAL (...)
+ def latest_for_projects(projects, order_by: 'released_at')
+ return Release.none if projects.empty?
+
+ projects_table = Project.arel_table
+ releases_table = Release.arel_table
+
+ join_query = Release
+ .where(projects_table[:id].eq(releases_table[:project_id]))
+ .sort_by_attribute("#{order_by}_desc")
+ .limit(1)
+
+ project_ids_list = projects.map { |project| "(#{project.id})" }.join(',')
+
+ Release
+ .from("(VALUES #{project_ids_list}) projects (id)")
+ .joins("INNER JOIN LATERAL (#{join_query.to_sql}) #{Release.table_name} ON TRUE")
+ end
+ end
+
def to_param
tag
end