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/ci/catalog/resource.rb')
-rw-r--r--app/models/ci/catalog/resource.rb57
1 files changed, 48 insertions, 9 deletions
diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb
index f947c5158cf..d1b3a3a4d8a 100644
--- a/app/models/ci/catalog/resource.rb
+++ b/app/models/ci/catalog/resource.rb
@@ -8,7 +8,8 @@ module Ci
# dependency on the Project model and its need to join with that table
# in order to generate the CI/CD catalog.
class Resource < ::ApplicationRecord
- include Gitlab::SQL::Pattern
+ include PgFullTextSearchable
+ include Gitlab::VisibilityLevel
self.table_name = 'catalog_resources'
@@ -17,9 +18,14 @@ module Ci
inverse_of: :catalog_resource
has_many :versions, class_name: 'Ci::Catalog::Resources::Version', foreign_key: :catalog_resource_id,
inverse_of: :catalog_resource
+ has_many :sync_events, class_name: 'Ci::Catalog::Resources::SyncEvent', foreign_key: :catalog_resource_id,
+ inverse_of: :catalog_resource
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
- scope :search, ->(query) { fuzzy_search(query, [:name, :description], use_minimum_char_limit: false) }
+
+ # The `search_vector` column contains a tsvector that has a greater weight on `name` than `description`.
+ # The vector is automatically generated by the database when `name` or `description` is updated.
+ scope :search, ->(query) { pg_full_text_search_in_model(query) }
scope :order_by_created_at_desc, -> { reorder(created_at: :desc) }
scope :order_by_created_at_asc, -> { reorder(created_at: :asc) }
@@ -28,14 +34,38 @@ module Ci
scope :order_by_latest_released_at_desc, -> { reorder(arel_table[:latest_released_at].desc.nulls_last) }
scope :order_by_latest_released_at_asc, -> { reorder(arel_table[:latest_released_at].asc.nulls_last) }
- delegate :avatar_path, :star_count, :forks_count, to: :project
+ delegate :avatar_path, :star_count, :full_path, to: :project
enum state: { draft: 0, published: 1 }
before_create :sync_with_project
- def unpublish!
- update!(state: :draft)
+ class << self
+ def public_or_visible_to_user(user)
+ return public_to_user unless user
+
+ where(
+ 'EXISTS (?) OR catalog_resources.visibility_level IN (?)',
+ user.authorizations_for_projects(related_project_column: 'catalog_resources.project_id'),
+ Gitlab::VisibilityLevel.levels_for_user(user)
+ )
+ end
+
+ def visible_to_user(user)
+ return none unless user
+
+ where_exists(user.authorizations_for_projects(related_project_column: 'catalog_resources.project_id'))
+ end
+
+ # Used by Ci::ProcessSyncEventsService
+ def sync!(event)
+ # There may be orphaned records since this table does not enforce FKs
+ event.catalog_resource&.sync_with_project!
+ end
+ end
+
+ def to_param
+ full_path
end
def publish!
@@ -47,12 +77,21 @@ module Ci
save!
end
+ # Triggered in Ci::Catalog::Resources::Version and Release model callbacks
+ def update_latest_released_at!
+ update!(latest_released_at: versions.latest&.released_at)
+ end
+
+ # Required for Gitlab::VisibilityLevel module
+ def visibility_level_field
+ :visibility_level
+ end
+
private
- # These columns are denormalized from the `projects` table. We first sync these
- # columns when the catalog resource record is created. Then any updates to the
- # `projects` columns will be synced to the `catalog_resources` table by a worker
- # (to be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/429376.)
+ # These denormalized columns are first synced when a new catalog resource is created.
+ # A PG trigger adds a SyncEvent when the associated project updates any of these columns.
+ # A worker processes the SyncEvents with Ci::ProcessSyncEventsService.
def sync_with_project
self.name = project.name
self.description = project.description