diff options
Diffstat (limited to 'lib/gitlab/background_migration')
72 files changed, 196 insertions, 2444 deletions
diff --git a/lib/gitlab/background_migration/add_merge_request_diff_commits_count.rb b/lib/gitlab/background_migration/add_merge_request_diff_commits_count.rb deleted file mode 100644 index 5b9ee8a0ee2..00000000000 --- a/lib/gitlab/background_migration/add_merge_request_diff_commits_count.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class AddMergeRequestDiffCommitsCount - class MergeRequestDiff < ActiveRecord::Base - self.table_name = 'merge_request_diffs' - end - - def perform(start_id, stop_id) - Gitlab::AppLogger.info("Setting commits_count for merge request diffs: #{start_id} - #{stop_id}") - - update = ' - commits_count = ( - SELECT count(*) - FROM merge_request_diff_commits - WHERE merge_request_diffs.id = merge_request_diff_commits.merge_request_diff_id - )'.squish - - MergeRequestDiff.where(id: start_id..stop_id).where(commits_count: nil).update_all(update) - end - end - end -end diff --git a/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule.rb b/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule.rb deleted file mode 100644 index 2148e96f6b4..00000000000 --- a/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Compare all current rules to project rules - class AddModifiedToApprovalMergeRequestRule - # Stubbed class to access the Group table - class Group < ActiveRecord::Base - self.table_name = 'namespaces' - self.inheritance_column = :_type_disabled - end - - # Stubbed class to access the ApprovalMergeRequestRule table - class ApprovalMergeRequestRule < ActiveRecord::Base - self.table_name = 'approval_merge_request_rules' - - has_one :approval_merge_request_rule_source, class_name: 'AddModifiedToApprovalMergeRequestRule::ApprovalMergeRequestRuleSource' - has_one :approval_project_rule, through: :approval_merge_request_rule_source - has_and_belongs_to_many :groups, - class_name: 'AddModifiedToApprovalMergeRequestRule::Group', join_table: "#{self.table_name}_groups" - end - - # Stubbed class to access the ApprovalProjectRule table - class ApprovalProjectRule < ActiveRecord::Base - self.table_name = 'approval_project_rules' - - has_many :approval_merge_request_rule_sources, class_name: 'AddModifiedToApprovalMergeRequestRule::ApprovalMergeRequestRuleSource' - has_and_belongs_to_many :groups, - class_name: 'AddModifiedToApprovalMergeRequestRule::Group', join_table: "#{self.table_name}_groups" - end - - # Stubbed class to access the ApprovalMergeRequestRuleSource table - class ApprovalMergeRequestRuleSource < ActiveRecord::Base - self.table_name = 'approval_merge_request_rule_sources' - - belongs_to :approval_merge_request_rule, class_name: 'AddModifiedToApprovalMergeRequestRule::ApprovalMergeRequestRule' - belongs_to :approval_project_rule, class_name: 'AddModifiedToApprovalMergeRequestRule::ApprovalProjectRule' - end - - def perform(start_id, stop_id) - approval_merge_requests_rules = ApprovalMergeRequestRule - .joins(:groups, :approval_merge_request_rule_source) - .where(id: start_id..stop_id) - .pluck( - 'approval_merge_request_rule_sources.id as ars_id', - 'approval_merge_request_rules_groups.id as amrg_id' - ) - - approval_project_rules = ApprovalProjectRule - .joins(:groups, approval_merge_request_rule_sources: :approval_merge_request_rule) - .where(approval_merge_request_rules: { id: start_id..stop_id }) - .pluck( - 'approval_merge_request_rule_sources.id as ars_id', - 'approval_project_rules_groups.id as apg_id' - ) - - different_names_or_approval_sources = ApprovalMergeRequestRule.joins(:approval_project_rule, :approval_merge_request_rule_source) - .where(id: start_id..stop_id) - .where('approval_merge_request_rules.name != approval_project_rules.name OR ' \ - 'approval_merge_request_rules.approvals_required != approval_project_rules.approvals_required') - .pluck('approval_merge_request_rule_sources.id as ars_id') - - intersected_set = approval_merge_requests_rules.to_set ^ approval_project_rules.to_set - source_ids = intersected_set.collect { |rule| rule[0] }.uniq - - rule_sources = ApprovalMergeRequestRuleSource.where(id: source_ids + different_names_or_approval_sources) - changed_merge_request_rules = ApprovalMergeRequestRule.where(id: rule_sources.select(:approval_merge_request_rule_id)) - - changed_merge_request_rules.update_all(modified_from_project_rule: true) - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments.rb b/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments.rb deleted file mode 100644 index 9778f360e87..00000000000 --- a/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Backfill deployment_clusters for a range of deployments - class BackfillDeploymentClustersFromDeployments - def perform(start_id, end_id) - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO deployment_clusters (deployment_id, cluster_id) - SELECT deployments.id, deployments.cluster_id - FROM deployments - WHERE deployments.cluster_id IS NOT NULL - AND deployments.id BETWEEN #{start_id} AND #{end_id} - ON CONFLICT DO NOTHING - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests.rb b/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests.rb deleted file mode 100644 index 4fd3b81fda3..00000000000 --- a/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # BackfillEnvironmentIdDeploymentMergeRequests deletes duplicates - # from deployment_merge_requests table and backfills environment_id - class BackfillEnvironmentIdDeploymentMergeRequests - def perform(_start_mr_id, _stop_mr_id) - # no-op - - # Background migration removed due to - # https://gitlab.com/gitlab-org/gitlab/-/issues/217191 - end - - def backfill_range(start_mr_id, stop_mr_id) - start_mr_id = Integer(start_mr_id) - stop_mr_id = Integer(stop_mr_id) - - ActiveRecord::Base.connection.execute(<<~SQL) - DELETE FROM deployment_merge_requests - WHERE (deployment_id, merge_request_id) in ( - SELECT t.deployment_id, t.merge_request_id FROM ( - SELECT mrd.merge_request_id, mrd.deployment_id, ROW_NUMBER() OVER w AS rnum - FROM deployment_merge_requests as mrd - INNER JOIN "deployments" ON "deployments"."id" = "mrd"."deployment_id" - WHERE mrd.merge_request_id BETWEEN #{start_mr_id} AND #{stop_mr_id} - WINDOW w AS ( - PARTITION BY merge_request_id, deployments.environment_id - ORDER BY deployments.id - ) - ) t - WHERE t.rnum > 1 - ); - SQL - - ActiveRecord::Base.connection.execute(<<~SQL) - UPDATE deployment_merge_requests - SET environment_id = deployments.environment_id - FROM deployments - WHERE deployments.id = "deployment_merge_requests".deployment_id - AND "deployment_merge_requests".environment_id IS NULL - AND "deployment_merge_requests".merge_request_id BETWEEN #{start_mr_id} AND #{stop_mr_id} - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules.rb b/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules.rb deleted file mode 100644 index 8a58cf9b302..00000000000 --- a/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Backfill merge request cleanup schedules of closed/merged merge requests - # without any corresponding records. - class BackfillMergeRequestCleanupSchedules - # Model used for migration added in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46782. - class MergeRequest < ActiveRecord::Base - include EachBatch - - self.table_name = 'merge_requests' - - def self.eligible - where('merge_requests.state_id IN (2, 3)') - end - end - - def perform(start_id, end_id) - eligible_mrs = MergeRequest.eligible.where(id: start_id..end_id) - scheduled_at_column = "COALESCE(metrics.merged_at, COALESCE(metrics.latest_closed_at, merge_requests.updated_at)) + interval '14 days'" - query = - eligible_mrs - .select("merge_requests.id, #{scheduled_at_column}, NOW(), NOW()") - .joins('LEFT JOIN merge_request_metrics metrics ON metrics.merge_request_id = merge_requests.id') - - result = ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO merge_request_cleanup_schedules (merge_request_id, scheduled_at, created_at, updated_at) - #{query.to_sql} - ON CONFLICT (merge_request_id) DO NOTHING; - SQL - - ::Gitlab::BackgroundMigration::Logger.info( - message: 'Backfilled merge_request_cleanup_schedules records', - count: result.cmd_tuples - ) - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_namespace_settings.rb b/lib/gitlab/background_migration/backfill_namespace_settings.rb deleted file mode 100644 index a391d5f4ebe..00000000000 --- a/lib/gitlab/background_migration/backfill_namespace_settings.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Backfillnamespace_settings for a range of namespaces - class BackfillNamespaceSettings - def perform(start_id, end_id) - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO namespace_settings (namespace_id, created_at, updated_at) - SELECT namespaces.id, now(), now() - FROM namespaces - WHERE namespaces.id BETWEEN #{start_id} AND #{end_id} - ON CONFLICT (namespace_id) DO NOTHING; - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_project_settings.rb b/lib/gitlab/background_migration/backfill_project_settings.rb deleted file mode 100644 index 7d7f19e1fda..00000000000 --- a/lib/gitlab/background_migration/backfill_project_settings.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Backfill project_settings for a range of projects - class BackfillProjectSettings - def perform(start_id, end_id) - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO project_settings (project_id, created_at, updated_at) - SELECT projects.id, now(), now() - FROM projects - WHERE projects.id BETWEEN #{start_id} AND #{end_id} - ON CONFLICT (project_id) DO NOTHING; - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_push_rules_id_in_projects.rb b/lib/gitlab/background_migration/backfill_push_rules_id_in_projects.rb deleted file mode 100644 index 9b9ef70424a..00000000000 --- a/lib/gitlab/background_migration/backfill_push_rules_id_in_projects.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Class that will insert record into project_push_rules - # for each existing push_rule - class BackfillPushRulesIdInProjects - # Temporary AR table for push rules - class ProjectSetting < ActiveRecord::Base - self.table_name = 'project_settings' - end - - def perform(start_id, stop_id) - ProjectSetting.connection.execute(<<~SQL) - UPDATE project_settings ps1 - SET push_rule_id = pr.id - FROM project_settings ps2 - INNER JOIN push_rules pr - ON ps2.project_id = pr.project_id - WHERE pr.is_sample = false - AND pr.id BETWEEN #{start_id} AND #{stop_id} - AND ps1.project_id = ps2.project_id - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/drop_invalid_remediations.rb b/lib/gitlab/background_migration/drop_invalid_remediations.rb new file mode 100644 index 00000000000..f0a0de586f5 --- /dev/null +++ b/lib/gitlab/background_migration/drop_invalid_remediations.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # rubocop: disable Style/Documentation + class DropInvalidRemediations + def perform(start_id, stop_id) + end + end + # rubocop: enable Style/Documentation + end +end + +Gitlab::BackgroundMigration::DropInvalidRemediations.prepend_mod_with('Gitlab::BackgroundMigration::DropInvalidRemediations') diff --git a/lib/gitlab/background_migration/drop_invalid_security_findings.rb b/lib/gitlab/background_migration/drop_invalid_security_findings.rb new file mode 100644 index 00000000000..87551bb1b1e --- /dev/null +++ b/lib/gitlab/background_migration/drop_invalid_security_findings.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true +module Gitlab + module BackgroundMigration + # Drop rows from security_findings where the uuid is NULL + class DropInvalidSecurityFindings + # rubocop:disable Style/Documentation + class SecurityFinding < ActiveRecord::Base + include ::EachBatch + self.table_name = 'security_findings' + scope :no_uuid, -> { where(uuid: nil) } + end + # rubocop:enable Style/Documentation + + PAUSE_SECONDS = 0.1 + + def perform(start_id, end_id, sub_batch_size) + ranged_query = SecurityFinding + .where(id: start_id..end_id) + .no_uuid + + ranged_query.each_batch(of: sub_batch_size) do |sub_batch| + first, last = sub_batch.pluck(Arel.sql('min(id), max(id)')).first + + # The query need to be reconstructed because .each_batch modifies the default scope + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/330510 + SecurityFinding.unscoped + .where(id: first..last) + .no_uuid + .delete_all + + sleep PAUSE_SECONDS + end + + mark_job_as_succeeded(start_id, end_id, sub_batch_size) + end + + private + + def mark_job_as_succeeded(*arguments) + Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded( + self.class.name.demodulize, + arguments + ) + end + end + end +end diff --git a/lib/gitlab/background_migration/fix_promoted_epics_discussion_ids.rb b/lib/gitlab/background_migration/fix_promoted_epics_discussion_ids.rb deleted file mode 100644 index 1a80ccdee92..00000000000 --- a/lib/gitlab/background_migration/fix_promoted_epics_discussion_ids.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This migration updates discussion ids for epics that were promoted from issue so that the discussion id on epics - # is different from discussion id on issue, which was causing problems when replying to epic discussions as it would - # identify the discussion as related to an issue and complaint about missing project_id - class FixPromotedEpicsDiscussionIds - # notes model to iterate through the notes to be updated - class Note < ActiveRecord::Base - self.table_name = 'notes' - self.inheritance_column = :_type_disabled - end - - def perform(discussion_ids) - Note.where(noteable_type: 'Epic') - .where(discussion_id: discussion_ids) - .update_all("discussion_id=MD5(discussion_id)||substring(discussion_id from 1 for 8)") - end - end - end -end diff --git a/lib/gitlab/background_migration/fix_user_namespace_names.rb b/lib/gitlab/background_migration/fix_user_namespace_names.rb deleted file mode 100644 index cd5b4ab103d..00000000000 --- a/lib/gitlab/background_migration/fix_user_namespace_names.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This migration fixes the namespaces.name for all user-namespaces that have names - # that aren't equal to the users name. - # Then it uses the updated names of the namespaces to update the associated routes - # For more info see https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/23272 - class FixUserNamespaceNames - def perform(from_id, to_id) - fix_namespace_names(from_id, to_id) - fix_namespace_route_names(from_id, to_id) - end - - def fix_namespace_names(from_id, to_id) - ActiveRecord::Base.connection.execute <<~UPDATE_NAMESPACES - WITH namespaces_to_update AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} ( - SELECT - namespaces.id, - users.name AS correct_name - FROM - namespaces - INNER JOIN users ON namespaces.owner_id = users.id - WHERE - namespaces.type IS NULL - AND namespaces.id BETWEEN #{from_id} AND #{to_id} - AND namespaces.name != users.name - ) - UPDATE - namespaces - SET - name = correct_name - FROM - namespaces_to_update - WHERE - namespaces.id = namespaces_to_update.id - UPDATE_NAMESPACES - end - - def fix_namespace_route_names(from_id, to_id) - ActiveRecord::Base.connection.execute <<~ROUTES_UPDATE - WITH routes_to_update AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} ( - SELECT - routes.id, - users.name AS correct_name - FROM - routes - INNER JOIN namespaces ON routes.source_id = namespaces.id - INNER JOIN users ON namespaces.owner_id = users.id - WHERE - namespaces.type IS NULL - AND routes.source_type = 'Namespace' - AND namespaces.id BETWEEN #{from_id} AND #{to_id} - AND (routes.name != users.name OR routes.name IS NULL) - ) - UPDATE - routes - SET - name = correct_name - FROM - routes_to_update - WHERE - routes_to_update.id = routes.id - ROUTES_UPDATE - end - end - end -end diff --git a/lib/gitlab/background_migration/fix_user_project_route_names.rb b/lib/gitlab/background_migration/fix_user_project_route_names.rb deleted file mode 100644 index e534f2449aa..00000000000 --- a/lib/gitlab/background_migration/fix_user_project_route_names.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This migration fixes the routes.name for all user-projects that have names - # that don't start with the users name. - # For more info see https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/23272 - class FixUserProjectRouteNames - def perform(from_id, to_id) - ActiveRecord::Base.connection.execute <<~ROUTES_UPDATE - WITH routes_to_update AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} ( - SELECT - routes.id, - users.name || ' / ' || projects.name AS correct_name - FROM - routes - INNER JOIN projects ON routes.source_id = projects.id - INNER JOIN namespaces ON projects.namespace_id = namespaces.id - INNER JOIN users ON namespaces.owner_id = users.id - WHERE - routes.source_type = 'Project' - AND routes.id BETWEEN #{from_id} AND #{to_id} - AND namespaces.type IS NULL - AND (routes.name NOT LIKE users.name || '%' OR routes.name IS NULL) - ) - UPDATE - routes - SET - name = routes_to_update.correct_name - FROM - routes_to_update - WHERE - routes_to_update.id = routes.id - ROUTES_UPDATE - end - end - end -end diff --git a/lib/gitlab/background_migration/job_coordinator.rb b/lib/gitlab/background_migration/job_coordinator.rb index 1c8819eaa62..cfbe7167677 100644 --- a/lib/gitlab/background_migration/job_coordinator.rb +++ b/lib/gitlab/background_migration/job_coordinator.rb @@ -8,24 +8,33 @@ module Gitlab # convention of how the queues and worker classes are setup for each database. # # Also provides a database connection to the correct tracking database. - class JobCoordinator - VALID_DATABASES = %i[main].freeze - WORKER_CLASS_NAME = 'BackgroundMigrationWorker' - - def self.for_database(database) - database = database.to_sym + class JobCoordinator # rubocop:disable Metrics/ClassLength + class << self + def worker_classes + @worker_classes ||= [ + BackgroundMigrationWorker + ].freeze + end - unless VALID_DATABASES.include?(database) - raise ArgumentError, "database must be one of [#{VALID_DATABASES.join(', ')}], got '#{database}'" + def worker_for_tracking_database + @worker_for_tracking_database ||= worker_classes + .index_by(&:tracking_database) + .with_indifferent_access + .freeze end - namespace = database.to_s.capitalize unless database == :main - namespaced_worker_class = [namespace, WORKER_CLASS_NAME].compact.join('::') + def for_tracking_database(tracking_database) + worker_class = worker_for_tracking_database[tracking_database] - new(database, "::#{namespaced_worker_class}".constantize) + if worker_class.nil? + raise ArgumentError, "tracking_database must be one of [#{worker_for_tracking_database.keys.join(', ')}]" + end + + new(worker_class) + end end - attr_reader :database, :worker_class + attr_reader :worker_class def queue @queue ||= worker_class.sidekiq_options['queue'] @@ -118,15 +127,14 @@ module Gitlab private - def initialize(database, worker_class) - @database = database + def initialize(worker_class) @worker_class = worker_class end def connection @connection ||= Gitlab::Database .database_base_models - .fetch(database, Gitlab::Database::PRIMARY_DATABASE_NAME) + .fetch(worker_class.tracking_database, Gitlab::Database::PRIMARY_DATABASE_NAME) .connection end end diff --git a/lib/gitlab/background_migration/link_lfs_objects_projects.rb b/lib/gitlab/background_migration/link_lfs_objects_projects.rb deleted file mode 100644 index 983470c5121..00000000000 --- a/lib/gitlab/background_migration/link_lfs_objects_projects.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Create missing LfsObjectsProject records for forks - class LinkLfsObjectsProjects - # Model specifically used for migration. - class LfsObjectsProject < ActiveRecord::Base - include EachBatch - - self.table_name = 'lfs_objects_projects' - - def self.linkable - where( - <<~SQL - lfs_objects_projects.project_id IN ( - SELECT fork_network_members.forked_from_project_id - FROM fork_network_members - WHERE fork_network_members.forked_from_project_id IS NOT NULL - ) - SQL - ) - end - end - - # Model specifically used for migration. - class ForkNetworkMember < ActiveRecord::Base - include EachBatch - - self.table_name = 'fork_network_members' - - def self.without_lfs_object(lfs_object_id) - where( - <<~SQL - fork_network_members.project_id NOT IN ( - SELECT lop.project_id - FROM lfs_objects_projects lop - WHERE lop.lfs_object_id = #{lfs_object_id} - ) - SQL - ) - end - end - - BATCH_SIZE = 1000 - - def perform(start_id, end_id) - lfs_objects_projects = - Gitlab::BackgroundMigration::LinkLfsObjectsProjects::LfsObjectsProject - .linkable - .where(id: start_id..end_id) - - return if lfs_objects_projects.empty? - - lfs_objects_projects.find_each do |lop| - ForkNetworkMember - .select("#{lop.lfs_object_id}, fork_network_members.project_id, NOW(), NOW()") - .without_lfs_object(lop.lfs_object_id) - .where(forked_from_project_id: lop.project_id) - .each_batch(of: BATCH_SIZE) do |batch, index| - execute <<~SQL - INSERT INTO lfs_objects_projects (lfs_object_id, project_id, created_at, updated_at) - #{batch.to_sql} - SQL - - logger.info(message: "LinkLfsObjectsProjects: created missing LfsObjectsProject records for LfsObject #{lop.lfs_object_id}") - end - end - end - - private - - def execute(sql) - ::ActiveRecord::Base.connection.execute(sql) - end - - def logger - @logger ||= Gitlab::BackgroundMigration::Logger.build - end - end - end -end diff --git a/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb b/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb deleted file mode 100644 index 36a339c6b80..00000000000 --- a/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class is responsible to update all sha256 fingerprints within the keys table - class MigrateFingerprintSha256WithinKeys - # Temporary AR table for keys - class Key < ActiveRecord::Base - include EachBatch - - self.table_name = 'keys' - self.inheritance_column = :_type_disabled - end - - TEMP_TABLE = 'tmp_fingerprint_sha256_migration' - - def perform(start_id, stop_id) - ActiveRecord::Base.transaction do - execute(<<~SQL) - CREATE TEMPORARY TABLE #{TEMP_TABLE} - (id bigint primary key, fingerprint_sha256 bytea not null) - ON COMMIT DROP - SQL - - fingerprints = [] - Key.where(id: start_id..stop_id, fingerprint_sha256: nil).find_each do |regular_key| - if fingerprint = generate_ssh_public_key(regular_key.key) - bytea = ActiveRecord::Base.connection.escape_bytea(Base64.decode64(fingerprint)) - - fingerprints << { - id: regular_key.id, - fingerprint_sha256: bytea - } - end - end - - ApplicationRecord.legacy_bulk_insert(TEMP_TABLE, fingerprints) # rubocop:disable Gitlab/BulkInsert - - execute("ANALYZE #{TEMP_TABLE}") - - execute(<<~SQL) - UPDATE keys - SET fingerprint_sha256 = t.fingerprint_sha256 - FROM #{TEMP_TABLE} t - WHERE keys.id = t.id - SQL - end - end - - private - - def generate_ssh_public_key(regular_key) - Gitlab::SSHPublicKey.new(regular_key).fingerprint("SHA256")&.gsub("SHA256:", "") - end - - def execute(query) - ActiveRecord::Base.connection.execute(query) - end - end - end -end diff --git a/lib/gitlab/background_migration/migrate_pages_metadata.rb b/lib/gitlab/background_migration/migrate_pages_metadata.rb deleted file mode 100644 index 68fd0c17d29..00000000000 --- a/lib/gitlab/background_migration/migrate_pages_metadata.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Class that will insert record into project_pages_metadata - # for each existing project - class MigratePagesMetadata - def perform(start_id, stop_id) - perform_on_relation(Project.where(id: start_id..stop_id)) - end - - def perform_on_relation(relation) - successful_pages_deploy = <<~SQL - SELECT TRUE - FROM ci_builds - WHERE ci_builds.type = 'GenericCommitStatus' - AND ci_builds.status = 'success' - AND ci_builds.stage = 'deploy' - AND ci_builds.name = 'pages:deploy' - AND ci_builds.project_id = projects.id - LIMIT 1 - SQL - - select_from = relation - .select("projects.id", "COALESCE((#{successful_pages_deploy}), FALSE)") - .to_sql - - ActiveRecord::Base.connection_pool.with_connection do |connection| - connection.execute <<~SQL - INSERT INTO project_pages_metadata (project_id, deployed) - #{select_from} - ON CONFLICT (project_id) DO NOTHING - SQL - end - end - end - end -end diff --git a/lib/gitlab/background_migration/migrate_to_hashed_storage.rb b/lib/gitlab/background_migration/migrate_to_hashed_storage.rb deleted file mode 100644 index 4054db4fb87..00000000000 --- a/lib/gitlab/background_migration/migrate_to_hashed_storage.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Background migration to move any legacy project to Hashed Storage - class MigrateToHashedStorage - def perform - batch_size = helper.batch_size - legacy_projects_count = Project.with_unmigrated_storage.count - - if storage_migrator.rollback_pending? - logger.warn( - migrator: 'MigrateToHashedStorage', - message: 'Aborting an storage rollback operation currently in progress' - ) - - storage_migrator.abort_rollback! - end - - if legacy_projects_count == 0 - logger.info( - migrator: 'MigrateToHashedStorage', - message: 'There are no projects requiring migration to Hashed Storage' - ) - - return - end - - logger.info( - migrator: 'MigrateToHashedStorage', - message: "Enqueuing migration of #{legacy_projects_count} projects in batches of #{batch_size}" - ) - - helper.project_id_batches_migration do |start, finish| - storage_migrator.bulk_schedule_migration(start: start, finish: finish) - - logger.info( - migrator: 'MigrateToHashedStorage', - message: "Enqueuing migration of projects in batches of #{batch_size} from ID=#{start} to ID=#{finish}", - batch_from: start, - batch_to: finish - ) - end - end - - private - - def helper - Gitlab::HashedStorage::RakeHelper - end - - def storage_migrator - @storage_migrator ||= Gitlab::HashedStorage::Migrator.new - end - - def logger - @logger ||= ::Gitlab::BackgroundMigration::Logger.build - end - end - end -end diff --git a/lib/gitlab/background_migration/move_epic_issues_after_epics.rb b/lib/gitlab/background_migration/move_epic_issues_after_epics.rb deleted file mode 100644 index 174994c7862..00000000000 --- a/lib/gitlab/background_migration/move_epic_issues_after_epics.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # rubocop: disable Style/Documentation - class MoveEpicIssuesAfterEpics - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::MoveEpicIssuesAfterEpics.prepend_mod_with('Gitlab::BackgroundMigration::MoveEpicIssuesAfterEpics') diff --git a/lib/gitlab/background_migration/populate_any_approval_rule_for_merge_requests.rb b/lib/gitlab/background_migration/populate_any_approval_rule_for_merge_requests.rb deleted file mode 100644 index 890a43800c9..00000000000 --- a/lib/gitlab/background_migration/populate_any_approval_rule_for_merge_requests.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This background migration creates any approver rule records according - # to the given merge request IDs range. A _single_ INSERT is issued for the given range. - class PopulateAnyApprovalRuleForMergeRequests - def perform(from_id, to_id) - end - end - end -end - -Gitlab::BackgroundMigration::PopulateAnyApprovalRuleForMergeRequests.prepend_mod_with('Gitlab::BackgroundMigration::PopulateAnyApprovalRuleForMergeRequests') diff --git a/lib/gitlab/background_migration/populate_any_approval_rule_for_projects.rb b/lib/gitlab/background_migration/populate_any_approval_rule_for_projects.rb deleted file mode 100644 index ac7ed18ba14..00000000000 --- a/lib/gitlab/background_migration/populate_any_approval_rule_for_projects.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This background migration creates any approver rule records according - # to the given project IDs range. A _single_ INSERT is issued for the given range. - class PopulateAnyApprovalRuleForProjects - def perform(from_id, to_id) - end - end - end -end - -Gitlab::BackgroundMigration::PopulateAnyApprovalRuleForProjects.prepend_mod_with('Gitlab::BackgroundMigration::PopulateAnyApprovalRuleForProjects') diff --git a/lib/gitlab/background_migration/populate_canonical_emails.rb b/lib/gitlab/background_migration/populate_canonical_emails.rb deleted file mode 100644 index 052e75c5655..00000000000 --- a/lib/gitlab/background_migration/populate_canonical_emails.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Class to populate new rows of UserCanonicalEmail based on existing email addresses - class PopulateCanonicalEmails - def perform(start_id, stop_id) - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO - user_canonical_emails ( - user_id, - canonical_email, - created_at, - updated_at - ) - SELECT users.id AS user_id, - concat(translate(split_part(split_part(users.email, '@', 1), '+', 1), '.', ''), '@gmail.com') AS canonical_email, - NOW() AS created_at, - NOW() AS updated_at - FROM users - WHERE users.email ILIKE '%@gmail.com' - AND users.id BETWEEN #{start_id} AND #{stop_id} - ON CONFLICT DO NOTHING; - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities.rb b/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities.rb deleted file mode 100644 index 68c91650d93..00000000000 --- a/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class updates vulnerabilities entities with state dismissed - class PopulateDismissedStateForVulnerabilities - class Vulnerability < ActiveRecord::Base # rubocop:disable Style/Documentation - self.table_name = 'vulnerabilities' - end - - def perform(*vulnerability_ids) - Vulnerability.where(id: vulnerability_ids).update_all(state: 2) - PopulateMissingVulnerabilityDismissalInformation.new.perform(*vulnerability_ids) - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_has_vulnerabilities.rb b/lib/gitlab/background_migration/populate_has_vulnerabilities.rb deleted file mode 100644 index 28ff2070209..00000000000 --- a/lib/gitlab/background_migration/populate_has_vulnerabilities.rb +++ /dev/null @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class populates missing dismissal information for - # vulnerability entries. - class PopulateHasVulnerabilities - class ProjectSetting < ActiveRecord::Base # rubocop:disable Style/Documentation - self.table_name = 'project_settings' - - def self.upsert_for(project_ids) - connection.execute(upsert_sql % { project_ids: project_ids.join(', ') }) - end - - def self.upsert_sql - <<~SQL - WITH upsert_data (project_id, has_vulnerabilities, created_at, updated_at) AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} ( - SELECT projects.id, true, current_timestamp, current_timestamp FROM projects WHERE projects.id IN (%{project_ids}) - ) - INSERT INTO project_settings - (project_id, has_vulnerabilities, created_at, updated_at) - (SELECT * FROM upsert_data) - ON CONFLICT (project_id) - DO UPDATE SET - has_vulnerabilities = true, - updated_at = EXCLUDED.updated_at - SQL - end - end - - class Vulnerability < ActiveRecord::Base # rubocop:disable Style/Documentation - include EachBatch - - self.table_name = 'vulnerabilities' - end - - def perform(*project_ids) - ProjectSetting.upsert_for(project_ids) - rescue StandardError => e - log_error(e, project_ids) - ensure - log_info(project_ids) - end - - private - - def log_error(error, project_ids) - ::Gitlab::BackgroundMigration::Logger.error( - migrator: self.class.name, - message: error.message, - project_ids: project_ids - ) - end - - def log_info(project_ids) - ::Gitlab::BackgroundMigration::Logger.info( - migrator: self.class.name, - message: 'Projects has been processed to populate `has_vulnerabilities` information', - count: project_ids.length - ) - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb b/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb deleted file mode 100644 index 28cc4a5e3fa..00000000000 --- a/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This background migration creates records on merge_request_assignees according - # to the given merge request IDs range. A _single_ INSERT is issued for the given range. - # This is required for supporting multiple assignees on merge requests. - class PopulateMergeRequestAssigneesTable - def perform(from_id, to_id) - select_sql = - MergeRequest - .where(merge_request_assignees_not_exists_clause) - .where(id: from_id..to_id) - .where.not(assignee_id: nil) - .select(:id, :assignee_id) - .to_sql - - execute("INSERT INTO merge_request_assignees (merge_request_id, user_id) #{select_sql}") - end - - def perform_all_sync(batch_size:) - MergeRequest.each_batch(of: batch_size) do |batch| - range = batch.pluck('MIN(id)', 'MAX(id)').first - - perform(*range) - end - end - - private - - def merge_request_assignees_not_exists_clause - <<~SQL - NOT EXISTS (SELECT 1 FROM merge_request_assignees - WHERE merge_request_assignees.merge_request_id = merge_requests.id) - SQL - end - - def execute(sql) - @connection ||= ActiveRecord::Base.connection - @connection.execute(sql) - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb b/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb deleted file mode 100644 index 04342fdabd4..00000000000 --- a/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class populates missing dismissal information for - # vulnerability entries. - class PopulateMissingVulnerabilityDismissalInformation - class Vulnerability < ActiveRecord::Base # rubocop:disable Style/Documentation - include EachBatch - - self.table_name = 'vulnerabilities' - - has_one :finding, class_name: '::Gitlab::BackgroundMigration::PopulateMissingVulnerabilityDismissalInformation::Finding' - - scope :broken, -> { where('state = 2 AND (dismissed_at IS NULL OR dismissed_by_id IS NULL)') } - - def copy_dismissal_information - return unless finding&.dismissal_feedback - - update_columns( - dismissed_at: finding.dismissal_feedback.created_at, - dismissed_by_id: finding.dismissal_feedback.author_id - ) - end - end - - class Finding < ActiveRecord::Base # rubocop:disable Style/Documentation - include ShaAttribute - include ::Gitlab::Utils::StrongMemoize - - self.table_name = 'vulnerability_occurrences' - - sha_attribute :project_fingerprint - - def dismissal_feedback - strong_memoize(:dismissal_feedback) do - Feedback.dismissal.where(category: report_type, project_fingerprint: project_fingerprint, project_id: project_id).first - end - end - end - - class Feedback < ActiveRecord::Base # rubocop:disable Style/Documentation - DISMISSAL_TYPE = 0 - - self.table_name = 'vulnerability_feedback' - - scope :dismissal, -> { where(feedback_type: DISMISSAL_TYPE) } - end - - def perform(*vulnerability_ids) - Vulnerability.includes(:finding).where(id: vulnerability_ids).each { |vulnerability| populate_for(vulnerability) } - - log_info(vulnerability_ids) - end - - private - - def populate_for(vulnerability) - log_warning(vulnerability) unless vulnerability.copy_dismissal_information - rescue StandardError => error - log_error(error, vulnerability) - end - - def log_info(vulnerability_ids) - ::Gitlab::BackgroundMigration::Logger.info( - migrator: self.class.name, - message: 'Dismissal information has been copied', - count: vulnerability_ids.length - ) - end - - def log_warning(vulnerability) - ::Gitlab::BackgroundMigration::Logger.warn( - migrator: self.class.name, - message: 'Could not update vulnerability!', - vulnerability_id: vulnerability.id - ) - end - - def log_error(error, vulnerability) - ::Gitlab::BackgroundMigration::Logger.error( - migrator: self.class.name, - message: error.message, - vulnerability_id: vulnerability.id - ) - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_personal_snippet_statistics.rb b/lib/gitlab/background_migration/populate_personal_snippet_statistics.rb deleted file mode 100644 index ed7ffce8018..00000000000 --- a/lib/gitlab/background_migration/populate_personal_snippet_statistics.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class creates/updates those personal snippets statistics - # that haven't been created nor initialized. - # It also updates the related root storage namespace stats - class PopulatePersonalSnippetStatistics - def perform(snippet_ids) - personal_snippets(snippet_ids).group_by(&:author).each do |author, author_snippets| - upsert_snippet_statistics(author_snippets) - update_namespace_statistics(author.namespace) - end - end - - private - - def personal_snippets(snippet_ids) - PersonalSnippet - .where(id: snippet_ids) - .includes(author: :namespace) - .includes(:statistics) - .includes(snippet_repository: :shard) - end - - def upsert_snippet_statistics(snippets) - snippets.each do |snippet| - response = Snippets::UpdateStatisticsService.new(snippet).execute - - error_message("#{response.message} snippet: #{snippet.id}") if response.error? - end - end - - def update_namespace_statistics(namespace) - Namespaces::StatisticsRefresherService.new.execute(namespace) - rescue StandardError => e - error_message("Error updating statistics for namespace #{namespace.id}: #{e.message}") - end - - def logger - @logger ||= Gitlab::BackgroundMigration::Logger.build - end - - def error_message(message) - logger.error(message: "Snippet Statistics Migration: #{message}") - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_project_snippet_statistics.rb b/lib/gitlab/background_migration/populate_project_snippet_statistics.rb deleted file mode 100644 index 37af320f044..00000000000 --- a/lib/gitlab/background_migration/populate_project_snippet_statistics.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class creates/updates those project snippets statistics - # that haven't been created nor initialized. - # It also updates the related project statistics and its root storage namespace stats - class PopulateProjectSnippetStatistics - def perform(snippet_ids) - project_snippets(snippet_ids).group_by(&:namespace_id).each do |namespace_id, namespace_snippets| - namespace_snippets.group_by(&:project).each do |project, snippets| - upsert_snippet_statistics(snippets) - update_project_statistics(project) - rescue StandardError - error_message("Error updating statistics for project #{project.id}") - end - - update_namespace_statistics(namespace_snippets.first.project.root_namespace) - rescue StandardError => e - error_message("Error updating statistics for namespace #{namespace_id}: #{e.message}") - end - end - - private - - def project_snippets(snippet_ids) - ProjectSnippet - .select('snippets.*, projects.namespace_id') - .where(id: snippet_ids) - .joins(:project) - .includes(:statistics) - .includes(snippet_repository: :shard) - .includes(project: [:route, :statistics, :namespace]) - end - - def upsert_snippet_statistics(snippets) - snippets.each do |snippet| - response = Snippets::UpdateStatisticsService.new(snippet).execute - - error_message("#{response.message} snippet: #{snippet.id}") if response.error? - end - end - - def logger - @logger ||= Gitlab::BackgroundMigration::Logger.build - end - - def error_message(message) - logger.error(message: "Snippet Statistics Migration: #{message}") - end - - def update_project_statistics(project) - project.statistics&.refresh!(only: [:snippets_size]) - end - - def update_namespace_statistics(namespace) - Namespaces::StatisticsRefresherService.new.execute(namespace) - end - end - end -end diff --git a/lib/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id.rb b/lib/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id.rb deleted file mode 100644 index 8241fea66db..00000000000 --- a/lib/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class updates vulnerability feedback entities with no pipeline id assigned. - class PopulateVulnerabilityFeedbackPipelineId - def perform(project_ids) - end - end - end -end - -Gitlab::BackgroundMigration::PopulateVulnerabilityFeedbackPipelineId.prepend_mod_with('Gitlab::BackgroundMigration::PopulateVulnerabilityFeedbackPipelineId') diff --git a/lib/gitlab/background_migration/populate_vulnerability_historical_statistics.rb b/lib/gitlab/background_migration/populate_vulnerability_historical_statistics.rb deleted file mode 100644 index 9a9f23e29ea..00000000000 --- a/lib/gitlab/background_migration/populate_vulnerability_historical_statistics.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This class creates/updates those project historical vulnerability statistics - # that haven't been created nor initialized. It should only be executed in EE. - class PopulateVulnerabilityHistoricalStatistics - def perform(project_ids, retention_period = 90) - end - end - end -end - -Gitlab::BackgroundMigration::PopulateVulnerabilityHistoricalStatistics.prepend_mod_with('Gitlab::BackgroundMigration::PopulateVulnerabilityHistoricalStatistics') diff --git a/lib/gitlab/background_migration/prune_orphaned_geo_events.rb b/lib/gitlab/background_migration/prune_orphaned_geo_events.rb deleted file mode 100644 index 0efbe72775c..00000000000 --- a/lib/gitlab/background_migration/prune_orphaned_geo_events.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# -# rubocop:disable Style/Documentation - -# This job is added to fix https://gitlab.com/gitlab-org/gitlab/issues/30229 -# It's not used anywhere else. -# Can be removed in GitLab 13.* -module Gitlab - module BackgroundMigration - class PruneOrphanedGeoEvents - def perform(table_name) - end - end - end -end - -Gitlab::BackgroundMigration::PruneOrphanedGeoEvents.prepend_mod_with('Gitlab::BackgroundMigration::PruneOrphanedGeoEvents') diff --git a/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id.rb b/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id.rb deleted file mode 100644 index b66fdfd5c65..00000000000 --- a/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # rubocop:disable Style/Documentation - class RecalculateProjectAuthorizationsWithMinMaxUserId - def perform(min_user_id, max_user_id) - User.where(id: min_user_id..max_user_id).find_each do |user| - service = Users::RefreshAuthorizedProjectsService.new( - user, - incorrect_auth_found_callback: - ->(project_id, access_level) do - logger.info(message: 'Removing ProjectAuthorizations', - user_id: user.id, - project_id: project_id, - access_level: access_level) - end, - missing_auth_found_callback: - ->(project_id, access_level) do - logger.info(message: 'Creating ProjectAuthorizations', - user_id: user.id, - project_id: project_id, - access_level: access_level) - end - ) - - service.execute - end - end - - private - - def logger - @logger ||= Gitlab::BackgroundMigration::Logger.build - end - end - end -end diff --git a/lib/gitlab/background_migration/migrate_security_scans.rb b/lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb index 0ae984f2dbc..20200a1d508 100644 --- a/lib/gitlab/background_migration/migrate_security_scans.rb +++ b/lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb @@ -3,11 +3,11 @@ module Gitlab module BackgroundMigration # rubocop: disable Style/Documentation - class MigrateSecurityScans + class RecalculateVulnerabilityFindingSignaturesForFindings def perform(start_id, stop_id) end end end end -Gitlab::BackgroundMigration::MigrateSecurityScans.prepend_mod_with('Gitlab::BackgroundMigration::MigrateSecurityScans') +Gitlab::BackgroundMigration::RecalculateVulnerabilityFindingSignaturesForFindings.prepend_mod diff --git a/lib/gitlab/background_migration/remove_duplicate_cs_findings.rb b/lib/gitlab/background_migration/remove_duplicate_cs_findings.rb deleted file mode 100644 index 17ef6dec4c0..00000000000 --- a/lib/gitlab/background_migration/remove_duplicate_cs_findings.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class RemoveDuplicateCsFindings - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::RemoveDuplicateCsFindings.prepend_mod_with('Gitlab::BackgroundMigration::RemoveDuplicateCsFindings') diff --git a/lib/gitlab/background_migration/remove_duplicated_cs_findings_without_vulnerability_id.rb b/lib/gitlab/background_migration/remove_duplicated_cs_findings_without_vulnerability_id.rb deleted file mode 100644 index e5772fc7375..00000000000 --- a/lib/gitlab/background_migration/remove_duplicated_cs_findings_without_vulnerability_id.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class RemoveDuplicatedCsFindingsWithoutVulnerabilityId - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::RemoveDuplicatedCsFindingsWithoutVulnerabilityId.prepend_mod_with('Gitlab::BackgroundMigration::RemoveDuplicatedCsFindingsWithoutVulnerabilityId') diff --git a/lib/gitlab/background_migration/remove_inaccessible_epic_todos.rb b/lib/gitlab/background_migration/remove_inaccessible_epic_todos.rb deleted file mode 100644 index cb6a600a525..00000000000 --- a/lib/gitlab/background_migration/remove_inaccessible_epic_todos.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # rubocop:disable Style/Documentation - class RemoveInaccessibleEpicTodos - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::RemoveInaccessibleEpicTodos.prepend_mod_with('Gitlab::BackgroundMigration::RemoveInaccessibleEpicTodos') diff --git a/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings.rb b/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings.rb new file mode 100644 index 00000000000..7fe5a427d10 --- /dev/null +++ b/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +# This migration will look for Vulnerabilities::Finding objects that would have a duplicate UUIDv5 if the UUID was +# recalculated. Then it removes Vulnerabilities::FindingPipeline objects associated with those Findings. +# We can't just drop those Findings directly since the cascade drop will timeout if any given Finding has too many +# associated FindingPipelines +class Gitlab::BackgroundMigration::RemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings + # rubocop:disable Gitlab/NamespacedClass, Style/Documentation + class VulnerabilitiesFinding < ActiveRecord::Base + self.table_name = "vulnerability_occurrences" + end + + class VulnerabilitiesFindingPipeline < ActiveRecord::Base + include EachBatch + self.table_name = "vulnerability_occurrence_pipelines" + end + # rubocop:enable Gitlab/NamespacedClass, Style/Documentation + + def perform(start_id, end_id) + ids_to_look_for = findings_that_would_produce_duplicate_uuids(start_id, end_id) + + ids_to_look_for.each do |finding_id| + VulnerabilitiesFindingPipeline.where(occurrence_id: finding_id).each_batch(of: 1000) do |pipelines| + pipelines.delete_all + end + end + + VulnerabilitiesFinding.where(id: ids_to_look_for).delete_all + + mark_job_as_succeeded(start_id, end_id) + end + + private + + def findings_that_would_produce_duplicate_uuids(start_id, end_id) + VulnerabilitiesFinding + .from("vulnerability_occurrences to_delete") + .where("to_delete.id BETWEEN ? AND ?", start_id, end_id) + .where( + "EXISTS ( + SELECT 1 + FROM vulnerability_occurrences duplicates + WHERE duplicates.report_type = to_delete.report_type + AND duplicates.location_fingerprint = to_delete.location_fingerprint + AND duplicates.primary_identifier_id = to_delete.primary_identifier_id + AND duplicates.project_id = to_delete.project_id + AND duplicates.id > to_delete.id + )" + ) + .pluck("to_delete.id") + end + + def mark_job_as_succeeded(*arguments) + Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded( + self.class.name.demodulize, + arguments + ) + end +end diff --git a/lib/gitlab/background_migration/remove_undefined_vulnerability_confidence_level.rb b/lib/gitlab/background_migration/remove_undefined_vulnerability_confidence_level.rb deleted file mode 100644 index 4be61bfb689..00000000000 --- a/lib/gitlab/background_migration/remove_undefined_vulnerability_confidence_level.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class RemoveUndefinedVulnerabilityConfidenceLevel - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::RemoveUndefinedVulnerabilityConfidenceLevel.prepend_mod_with('Gitlab::BackgroundMigration::RemoveUndefinedVulnerabilityConfidenceLevel') diff --git a/lib/gitlab/background_migration/remove_vulnerability_finding_links.rb b/lib/gitlab/background_migration/remove_vulnerability_finding_links.rb new file mode 100644 index 00000000000..31fb5e97c5d --- /dev/null +++ b/lib/gitlab/background_migration/remove_vulnerability_finding_links.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # Remove vulnerability finding link records + # The records will be repopulated from the `raw_metadata` + # column of `vulnerability_occurrences` once the unique + # index is in place. + class RemoveVulnerabilityFindingLinks + include Gitlab::Database::DynamicModelHelpers + + def perform(start_id, stop_id) + define_batchable_model('vulnerability_finding_links').where(id: start_id..stop_id).delete_all + end + end + end +end diff --git a/lib/gitlab/background_migration/replace_blocked_by_links.rb b/lib/gitlab/background_migration/replace_blocked_by_links.rb deleted file mode 100644 index 0c29887bb00..00000000000 --- a/lib/gitlab/background_migration/replace_blocked_by_links.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class ReplaceBlockedByLinks - class IssueLink < ActiveRecord::Base - self.table_name = 'issue_links' - end - - def perform(start_id, stop_id) - blocked_by_links = IssueLink.where(id: start_id..stop_id).where(link_type: 2) - - ActiveRecord::Base.transaction do - # There could be two edge cases: - # 1) issue1 is blocked by issue2 AND issue2 blocks issue1 (type 1) - # 2) issue1 is blocked by issue2 AND issue2 is related to issue1 (type 0) - # In both cases cases we couldn't convert blocked by relation to - # `issue2 blocks issue` because there is already a link with the same - # source/target id. To avoid these conflicts, we first delete any - # "opposite" links before we update `blocked by` relation. This - # should be rare as we have a pre-create check which checks if issues - # are already linked - opposite_ids = blocked_by_links - .select('opposite_links.id') - .joins('INNER JOIN issue_links as opposite_links ON issue_links.source_id = opposite_links.target_id AND issue_links.target_id = opposite_links.source_id') - IssueLink.where(id: opposite_ids).delete_all - - blocked_by_links.update_all('source_id=target_id,target_id=source_id,link_type=1') - end - end - end - end -end diff --git a/lib/gitlab/background_migration/reset_merge_status.rb b/lib/gitlab/background_migration/reset_merge_status.rb deleted file mode 100644 index d040b4931be..00000000000 --- a/lib/gitlab/background_migration/reset_merge_status.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Updates the range of given MRs to merge_status "unchecked", if they're opened - # and mergeable. - class ResetMergeStatus - def perform(from_id, to_id) - relation = MergeRequest.where(id: from_id..to_id, - state_id: 1, # opened - merge_status: 'can_be_merged') - - relation.update_all(merge_status: 'unchecked') - end - end - end -end diff --git a/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects.rb b/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects.rb deleted file mode 100644 index 0053cafb4ac..00000000000 --- a/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Resets inconsistent state of shared_runners_enabled for projects that have been transferred - class ResetSharedRunnersForTransferredProjects - # Model specifically used for migration. - class Namespace < ActiveRecord::Base - include EachBatch - - self.table_name = 'namespaces' - end - - # Model specifically used for migration. - class Project < ActiveRecord::Base - self.table_name = 'projects' - end - - def perform(start_id, stop_id) - Project.reset_column_information - - Namespace.where(id: start_id..stop_id).each_batch(of: 1_000) do |relation| - ids = relation.where(shared_runners_enabled: false, allow_descendants_override_disabled_shared_runners: false).select(:id) - - Project.where(namespace_id: ids).update_all(shared_runners_enabled: false) - end - end - end - end -end diff --git a/lib/gitlab/background_migration/set_merge_request_diff_files_count.rb b/lib/gitlab/background_migration/set_merge_request_diff_files_count.rb deleted file mode 100644 index 527dd2a0a83..00000000000 --- a/lib/gitlab/background_migration/set_merge_request_diff_files_count.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # Sets the MergeRequestDiff#files_count value for old rows - class SetMergeRequestDiffFilesCount - # Some historic data has a *lot* of files. Apply a sentinel to these cases - FILES_COUNT_SENTINEL = 2**15 - 1 - - def self.count_subquery - <<~SQL - files_count = ( - SELECT LEAST(#{FILES_COUNT_SENTINEL}, count(*)) - FROM merge_request_diff_files - WHERE merge_request_diff_files.merge_request_diff_id = merge_request_diffs.id - ) - SQL - end - - class MergeRequestDiff < ActiveRecord::Base # rubocop:disable Style/Documentation - include EachBatch - - self.table_name = 'merge_request_diffs' - end - - def perform(start_id, end_id) - MergeRequestDiff.where(id: start_id..end_id).each_batch do |relation| - relation.update_all(self.class.count_subquery) - end - end - end - end -end diff --git a/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent.rb b/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent.rb deleted file mode 100644 index 9e330f7c008..00000000000 --- a/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # This background migration updates children of group to match visibility of a parent - class UpdateExistingSubgroupToMatchVisibilityLevelOfParent - def perform(parents_groups_ids, level) - groups_ids = Gitlab::ObjectHierarchy.new(Group.where(id: parents_groups_ids)) - .base_and_descendants - .where("visibility_level > ?", level) - .select(:id) - - return if groups_ids.empty? - - Group - .where(id: groups_ids) - .update_all(visibility_level: level) - end - end - end -end diff --git a/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth.rb b/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth.rb deleted file mode 100644 index d97765cd398..00000000000 --- a/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class UpdateExistingUsersThatRequireTwoFactorAuth # rubocop:disable Metrics/ClassLength - def perform(start_id, stop_id) - ActiveRecord::Base.connection.execute <<~SQL - UPDATE - users - SET - require_two_factor_authentication_from_group = FALSE - WHERE - users.id BETWEEN #{start_id} - AND #{stop_id} - AND users.require_two_factor_authentication_from_group = TRUE - AND users.id NOT IN ( SELECT DISTINCT - users_groups_query.user_id - FROM ( - SELECT - users.id AS user_id, - members.source_id AS group_ids - FROM - users - LEFT JOIN members ON members.source_type = 'Namespace' - AND members.requested_at IS NULL - AND members.user_id = users.id - AND members.type = 'GroupMember' - WHERE - users.require_two_factor_authentication_from_group = TRUE - AND users.id BETWEEN #{start_id} - AND #{stop_id}) AS users_groups_query - INNER JOIN LATERAL ( WITH RECURSIVE "base_and_ancestors" AS ( - ( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "namespaces" - WHERE - "namespaces"."type" = 'Group' - AND "namespaces"."id" = users_groups_query.group_ids) - UNION ( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "namespaces", - "base_and_ancestors" - WHERE - "namespaces"."type" = 'Group' - AND "namespaces"."id" = "base_and_ancestors"."parent_id")), - "base_and_descendants" AS ( - ( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "namespaces" - WHERE - "namespaces"."type" = 'Group' - AND "namespaces"."id" = users_groups_query.group_ids) - UNION ( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "namespaces", - "base_and_descendants" - WHERE - "namespaces"."type" = 'Group' - AND "namespaces"."parent_id" = "base_and_descendants"."id")) - SELECT - "namespaces".* - FROM (( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "base_and_ancestors" AS "namespaces" - WHERE - "namespaces"."type" = 'Group') - UNION ( - SELECT - "namespaces"."type", - "namespaces"."id", - "namespaces"."parent_id", - "namespaces"."require_two_factor_authentication" - FROM - "base_and_descendants" AS "namespaces" - WHERE - "namespaces"."type" = 'Group')) namespaces - WHERE - "namespaces"."type" = 'Group' - AND "namespaces"."require_two_factor_authentication" = TRUE) AS hierarchy_tree ON TRUE); - SQL - end - end - end -end diff --git a/lib/gitlab/background_migration/update_location_fingerprint_for_container_scanning_findings.rb b/lib/gitlab/background_migration/update_location_fingerprint_for_container_scanning_findings.rb deleted file mode 100644 index 054b918dade..00000000000 --- a/lib/gitlab/background_migration/update_location_fingerprint_for_container_scanning_findings.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - class UpdateLocationFingerprintForContainerScanningFindings - def perform(start_id, stop_id) - end - end - end -end - -Gitlab::BackgroundMigration::UpdateLocationFingerprintForContainerScanningFindings.prepend_mod_with('Gitlab::BackgroundMigration::UpdateLocationFingerprintForContainerScanningFindings') diff --git a/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb b/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb new file mode 100644 index 00000000000..c95ef9f5515 --- /dev/null +++ b/lib/gitlab/background_migration/update_timelogs_null_spent_at.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # Class to populate spent_at for timelogs + class UpdateTimelogsNullSpentAt + include Gitlab::Database::DynamicModelHelpers + + BATCH_SIZE = 100 + + def perform(start_id, stop_id) + define_batchable_model('timelogs').where(spent_at: nil, id: start_id..stop_id).each_batch(of: 100) do |subbatch| + batch_start, batch_end = subbatch.pluck('min(id), max(id)').first + + update_timelogs(batch_start, batch_end) + end + end + + def update_timelogs(batch_start, batch_stop) + execute(<<~SQL) + UPDATE timelogs + SET spent_at = created_at + WHERE spent_at IS NULL + AND timelogs.id BETWEEN #{batch_start} AND #{batch_stop}; + SQL + end + + def execute(sql) + @connection ||= ::ActiveRecord::Base.connection + @connection.execute(sql) + end + end + end +end diff --git a/lib/gitlab/background_migration/update_vulnerabilities_from_dismissal_feedback.rb b/lib/gitlab/background_migration/update_vulnerabilities_from_dismissal_feedback.rb deleted file mode 100644 index 1cc03f061fb..00000000000 --- a/lib/gitlab/background_migration/update_vulnerabilities_from_dismissal_feedback.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - # rubocop: disable Style/Documentation - class UpdateVulnerabilitiesFromDismissalFeedback - def perform(project_id) - end - end - end -end - -Gitlab::BackgroundMigration::UpdateVulnerabilitiesFromDismissalFeedback.prepend_mod_with('Gitlab::BackgroundMigration::UpdateVulnerabilitiesFromDismissalFeedback') diff --git a/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb b/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb deleted file mode 100644 index b3876018553..00000000000 --- a/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - class CreateResourceUserMention - # Resources that have mentions to be migrated: - # issue, merge_request, epic, commit, snippet, design - - BULK_INSERT_SIZE = 1_000 - ISOLATION_MODULE = 'Gitlab::BackgroundMigration::UserMentions::Models' - - def perform(resource_model, join, conditions, with_notes, start_id, end_id) - return unless Feature.enabled?(:migrate_user_mentions, default_enabled: true) - - resource_model = "#{ISOLATION_MODULE}::#{resource_model}".constantize if resource_model.is_a?(String) - model = with_notes ? Gitlab::BackgroundMigration::UserMentions::Models::Note : resource_model - resource_user_mention_model = resource_model.user_mention_model - - records = model.joins(join).where(conditions).where(id: start_id..end_id) - - records.each_batch(of: BULK_INSERT_SIZE) do |records| - mentions = [] - records.each do |record| - mention_record = record.build_mention_values(resource_user_mention_model.resource_foreign_key) - mentions << mention_record unless mention_record.blank? - end - - resource_user_mention_model.insert_all(mentions) unless mentions.empty? - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser.rb b/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser.rb deleted file mode 100644 index 3def5eb3369..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Banzai - # isolated Banzai::ReferenceParser - module ReferenceParser - # Returns the reference parser class for the given type - # - # Example: - # - # Banzai::ReferenceParser['isolated_mentioned_group'] - # - # This would return the `::Gitlab::BackgroundMigration::UserMentions::Lib::Banzai::ReferenceParser::IsolatedMentionedGroupParser` class. - def self.[](name) - const_get("::Gitlab::BackgroundMigration::UserMentions::Lib::Banzai::ReferenceParser::#{name.to_s.camelize}Parser", false) - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_group_parser.rb b/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_group_parser.rb deleted file mode 100644 index d3d032ba433..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_group_parser.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Banzai - module ReferenceParser - # isolated Banzai::ReferenceParser::MentionedGroupParser - class IsolatedMentionedGroupParser < ::Banzai::ReferenceParser::MentionedGroupParser - extend ::Gitlab::Utils::Override - - self.reference_type = :user - - override :references_relation - def references_relation - ::Gitlab::BackgroundMigration::UserMentions::Models::Group - end - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_project_parser.rb b/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_project_parser.rb deleted file mode 100644 index 5930d65bc2c..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_project_parser.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Banzai - module ReferenceParser - # isolated Banzai::ReferenceParser::MentionedGroupParser - class IsolatedMentionedProjectParser < ::Banzai::ReferenceParser::MentionedProjectParser - extend ::Gitlab::Utils::Override - - self.reference_type = :user - - override :references_relation - def references_relation - ::Gitlab::BackgroundMigration::UserMentions::Models::Project - end - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_user_parser.rb b/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_user_parser.rb deleted file mode 100644 index f5f98517433..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/banzai/reference_parser/isolated_mentioned_user_parser.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Banzai - module ReferenceParser - # isolated Banzai::ReferenceParser::MentionedGroupParser - class IsolatedMentionedUserParser < ::Banzai::ReferenceParser::MentionedUserParser - extend ::Gitlab::Utils::Override - - self.reference_type = :user - - override :references_relation - def references_relation - ::Gitlab::BackgroundMigration::UserMentions::Models::User - end - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_reference_extractor.rb b/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_reference_extractor.rb deleted file mode 100644 index 8610129533d..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_reference_extractor.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Gitlab - # Extract possible GFM references from an arbitrary String for further processing. - class IsolatedReferenceExtractor < ::Gitlab::ReferenceExtractor - REFERABLES = %i(isolated_mentioned_group isolated_mentioned_user isolated_mentioned_project).freeze - - REFERABLES.each do |type| - define_method("#{type}s") do - @references[type] ||= isolated_references(type) - end - end - - def isolated_references(type) - context = ::Banzai::RenderContext.new(project, current_user) - processor = ::Gitlab::BackgroundMigration::UserMentions::Lib::Banzai::ReferenceParser[type].new(context) - - refs = processor.process(html_documents) - refs[:visible] - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_visibility_level.rb b/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_visibility_level.rb deleted file mode 100644 index 0334ea1dd08..00000000000 --- a/lib/gitlab/background_migration/user_mentions/lib/gitlab/isolated_visibility_level.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Lib - module Gitlab - # Gitlab::IsolatedVisibilityLevel module - # - # Define allowed public modes that can be used for - # GitLab projects to determine project public mode - # - module IsolatedVisibilityLevel - extend ::ActiveSupport::Concern - - included do - scope :public_to_user, -> (user = nil) do - where(visibility_level: IsolatedVisibilityLevel.levels_for_user(user)) - end - end - - PRIVATE = 0 unless const_defined?(:PRIVATE) - INTERNAL = 10 unless const_defined?(:INTERNAL) - PUBLIC = 20 unless const_defined?(:PUBLIC) - - class << self - def levels_for_user(user = nil) - return [PUBLIC] unless user - - if user.can_read_all_resources? - [PRIVATE, INTERNAL, PUBLIC] - elsif user.external? - [PUBLIC] - else - [INTERNAL, PUBLIC] - end - end - end - - def private? - visibility_level_value == PRIVATE - end - - def internal? - visibility_level_value == INTERNAL - end - - def public? - visibility_level_value == PUBLIC - end - - def visibility_level_value - self[visibility_level_field] - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/commit.rb b/lib/gitlab/background_migration/user_mentions/models/commit.rb deleted file mode 100644 index 65f4a7a25b6..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/commit.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class Commit - include EachBatch - include Concerns::IsolatedMentionable - include Concerns::MentionableMigrationMethods - - def self.user_mention_model - Gitlab::BackgroundMigration::UserMentions::Models::CommitUserMention - end - - def user_mention_model - self.class.user_mention_model - end - - def user_mention_resource_id - id - end - - def user_mention_note_id - 'NULL' - end - - def self.no_quote_columns - [:note_id] - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/commit_user_mention.rb b/lib/gitlab/background_migration/user_mentions/models/commit_user_mention.rb deleted file mode 100644 index f4cc96c8bc0..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/commit_user_mention.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class CommitUserMention < ActiveRecord::Base - self.table_name = 'commit_user_mentions' - self.inheritance_column = :_type_disabled - - def self.resource_foreign_key - :commit_id - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_feature_gate.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_feature_gate.rb deleted file mode 100644 index ba6b783f9f1..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_feature_gate.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - module Concerns - # isolated FeatureGate module - module IsolatedFeatureGate - def flipper_id - return if new_record? - - "#{self.class.name}:#{id}" - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb deleted file mode 100644 index f684f789ea9..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb +++ /dev/null @@ -1,104 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - module Concerns - # == IsolatedMentionable concern - # - # Shortcutted for isolation version of Mentionable to be used in mentions migrations - # - module IsolatedMentionable - extend ::ActiveSupport::Concern - - class_methods do - # Indicate which attributes of the Mentionable to search for GFM references. - def attr_mentionable(attr, options = {}) - attr = attr.to_s - mentionable_attrs << [attr, options] - end - end - - included do - # Accessor for attributes marked mentionable. - cattr_accessor :mentionable_attrs, instance_accessor: false do - [] - end - - if self < Participable - participant -> (user, ext) { all_references(user, extractor: ext) } - end - end - - def all_references(current_user = nil, extractor: nil) - # Use custom extractor if it's passed in the function parameters. - if extractor - extractors[current_user] = extractor - else - extractor = extractors[current_user] ||= - Gitlab::BackgroundMigration::UserMentions::Lib::Gitlab::IsolatedReferenceExtractor.new(project, current_user) - - extractor.reset_memoized_values - end - - self.class.mentionable_attrs.each do |attr, options| - text = __send__(attr) # rubocop:disable GitlabSecurity/PublicSend - options = options.merge( - cache_key: [self, attr], - author: author, - skip_project_check: skip_project_check? - ).merge(mentionable_params) - - cached_html = self.try(:updated_cached_html_for, attr.to_sym) - options[:rendered] = cached_html if cached_html - - extractor.analyze(text, options) - end - - extractor - end - - def extractors - @extractors ||= {} - end - - def skip_project_check? - false - end - - def build_mention_values(resource_foreign_key) - refs = all_references(author) - - mentioned_users_ids = array_to_sql(refs.isolated_mentioned_users.pluck(:id)) - mentioned_projects_ids = array_to_sql(refs.isolated_mentioned_projects.pluck(:id)) - mentioned_groups_ids = array_to_sql(refs.isolated_mentioned_groups.pluck(:id)) - - return if mentioned_users_ids.blank? && mentioned_projects_ids.blank? && mentioned_groups_ids.blank? - - { - "#{resource_foreign_key}": user_mention_resource_id, - note_id: user_mention_note_id, - mentioned_users_ids: mentioned_users_ids, - mentioned_projects_ids: mentioned_projects_ids, - mentioned_groups_ids: mentioned_groups_ids - } - end - - def array_to_sql(ids_array) - return unless ids_array.present? - - '{' + ids_array.join(", ") + '}' - end - - private - - def mentionable_params - {} - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb deleted file mode 100644 index efb08d44100..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - module Concerns - # Extract common no_quote_columns method used in determining the columns that do not need - # to be quoted for corresponding models - module MentionableMigrationMethods - extend ::ActiveSupport::Concern - - class_methods do - def no_quote_columns - [ - :note_id, - user_mention_model.resource_foreign_key - ] - end - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/namespace/recursive_traversal.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/namespace/recursive_traversal.rb deleted file mode 100644 index 75759ed0111..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/concerns/namespace/recursive_traversal.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - module Concerns - module Namespace - # isolate recursive traversal code for namespace hierarchy - module RecursiveTraversal - extend ActiveSupport::Concern - - def root_ancestor - return self if persisted? && parent_id.nil? - - strong_memoize(:root_ancestor) do - Gitlab::ObjectHierarchy - .new(self.class.where(id: id)) - .base_and_ancestors - .reorder(nil) - .find_by(parent_id: nil) - end - end - - # Returns all ancestors, self, and descendants of the current namespace. - def self_and_hierarchy - Gitlab::ObjectHierarchy - .new(self.class.where(id: id)) - .all_objects - end - - # Returns all the ancestors of the current namespaces. - def ancestors - return self.class.none unless parent_id - - Gitlab::ObjectHierarchy - .new(self.class.where(id: parent_id)) - .base_and_ancestors - end - - # returns all ancestors upto but excluding the given namespace - # when no namespace is given, all ancestors upto the top are returned - def ancestors_upto(top = nil, hierarchy_order: nil) - Gitlab::ObjectHierarchy.new(self.class.where(id: id)) - .ancestors(upto: top, hierarchy_order: hierarchy_order) - end - - def self_and_ancestors(hierarchy_order: nil) - return self.class.where(id: id) unless parent_id - - Gitlab::ObjectHierarchy - .new(self.class.where(id: id)) - .base_and_ancestors(hierarchy_order: hierarchy_order) - end - - # Returns all the descendants of the current namespace. - def descendants - Gitlab::ObjectHierarchy - .new(self.class.where(parent_id: id)) - .base_and_descendants - end - - def self_and_descendants - Gitlab::ObjectHierarchy - .new(self.class.where(id: id)) - .base_and_descendants - end - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/design_management/design.rb b/lib/gitlab/background_migration/user_mentions/models/design_management/design.rb deleted file mode 100644 index d010d68600d..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/design_management/design.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - module DesignManagement - class Design < ActiveRecord::Base - include EachBatch - include Concerns::MentionableMigrationMethods - - self.table_name = 'design_management_designs' - self.inheritance_column = :_type_disabled - - def self.user_mention_model - Gitlab::BackgroundMigration::UserMentions::Models::DesignUserMention - end - - def user_mention_model - self.class.user_mention_model - end - - def user_mention_resource_id - id - end - - def user_mention_note_id - 'NULL' - end - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/design_user_mention.rb b/lib/gitlab/background_migration/user_mentions/models/design_user_mention.rb deleted file mode 100644 index eb00f6cfa3f..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/design_user_mention.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class DesignUserMention < ActiveRecord::Base - self.table_name = 'design_user_mentions' - self.inheritance_column = :_type_disabled - - def self.resource_foreign_key - :design_id - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/epic.rb b/lib/gitlab/background_migration/user_mentions/models/epic.rb deleted file mode 100644 index cfd9a4faa9b..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/epic.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class Epic < ActiveRecord::Base - include EachBatch - include Concerns::IsolatedMentionable - include Concerns::MentionableMigrationMethods - include CacheMarkdownField - - attr_mentionable :title, pipeline: :single_line - attr_mentionable :description - cache_markdown_field :title, pipeline: :single_line - cache_markdown_field :description, issuable_state_filter_enabled: true - - self.table_name = 'epics' - self.inheritance_column = :_type_disabled - - belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User" - belongs_to :group, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Group" - - def self.user_mention_model - Gitlab::BackgroundMigration::UserMentions::Models::EpicUserMention - end - - def user_mention_model - self.class.user_mention_model - end - - def project - nil - end - - def mentionable_params - { group: group, label_url_method: :group_epics_url } - end - - def user_mention_resource_id - id - end - - def user_mention_note_id - 'NULL' - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/epic_user_mention.rb b/lib/gitlab/background_migration/user_mentions/models/epic_user_mention.rb deleted file mode 100644 index 579e4d99612..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/epic_user_mention.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class EpicUserMention < ActiveRecord::Base - self.table_name = 'epic_user_mentions' - self.inheritance_column = :_type_disabled - - def self.resource_foreign_key - :epic_id - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/group.rb b/lib/gitlab/background_migration/user_mentions/models/group.rb deleted file mode 100644 index 310723570c2..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/group.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - # isolated Group model - class Group < ::Gitlab::BackgroundMigration::UserMentions::Models::Namespace - self.store_full_sti_class = false - self.inheritance_column = :_type_disabled - - has_one :saml_provider - - def root_saml_provider - root_ancestor.saml_provider - end - - def self.declarative_policy_class - "GroupPolicy" - end - - def max_member_access_for_user(user) - return GroupMember::NO_ACCESS unless user - - return GroupMember::OWNER if user.admin? - - max_member_access = members_with_parents.where(user_id: user) - .reorder(access_level: :desc) - .first - &.access_level - - max_member_access || GroupMember::NO_ACCESS - end - - def members_with_parents - # Avoids an unnecessary SELECT when the group has no parents - source_ids = - if has_parent? - self_and_ancestors.reorder(nil).select(:id) - else - id - end - - group_hierarchy_members = GroupMember.active_without_invites_and_requests - .where(source_id: source_ids) - - GroupMember.from_union([group_hierarchy_members, - members_from_self_and_ancestor_group_shares]) - end - - # rubocop: disable Metrics/AbcSize - def members_from_self_and_ancestor_group_shares - group_group_link_table = GroupGroupLink.arel_table - group_member_table = GroupMember.arel_table - - source_ids = - if has_parent? - self_and_ancestors.reorder(nil).select(:id) - else - id - end - - group_group_links_query = GroupGroupLink.where(shared_group_id: source_ids) - cte = Gitlab::SQL::CTE.new(:group_group_links_cte, group_group_links_query) - cte_alias = cte.table.alias(GroupGroupLink.table_name) - - # Instead of members.access_level, we need to maximize that access_level at - # the respective group_group_links.group_access. - member_columns = GroupMember.attribute_names.map do |column_name| - if column_name == 'access_level' - smallest_value_arel([cte_alias[:group_access], group_member_table[:access_level]], - 'access_level') - else - group_member_table[column_name] - end - end - - GroupMember - .with(cte.to_arel) - .select(*member_columns) - .from([group_member_table, cte.alias_to(group_group_link_table)]) - .where(group_member_table[:requested_at].eq(nil)) - .where(group_member_table[:source_id].eq(group_group_link_table[:shared_with_group_id])) - .where(group_member_table[:source_type].eq('Namespace')) - end - # rubocop: enable Metrics/AbcSize - - def smallest_value_arel(args, column_alias) - Arel::Nodes::As.new( - Arel::Nodes::NamedFunction.new('LEAST', args), - Arel::Nodes::SqlLiteral.new(column_alias)) - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/merge_request.rb b/lib/gitlab/background_migration/user_mentions/models/merge_request.rb deleted file mode 100644 index 13addcc3c55..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/merge_request.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class MergeRequest < ActiveRecord::Base - include EachBatch - include Concerns::IsolatedMentionable - include CacheMarkdownField - include Concerns::MentionableMigrationMethods - - attr_mentionable :title, pipeline: :single_line - attr_mentionable :description - cache_markdown_field :title, pipeline: :single_line - cache_markdown_field :description, issuable_state_filter_enabled: true - - self.table_name = 'merge_requests' - self.inheritance_column = :_type_disabled - - belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User" - belongs_to :target_project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project" - belongs_to :source_project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project" - - alias_attribute :project, :target_project - - def self.user_mention_model - Gitlab::BackgroundMigration::UserMentions::Models::MergeRequestUserMention - end - - def user_mention_model - self.class.user_mention_model - end - - def user_mention_resource_id - id - end - - def user_mention_note_id - 'NULL' - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/merge_request_user_mention.rb b/lib/gitlab/background_migration/user_mentions/models/merge_request_user_mention.rb deleted file mode 100644 index 4a85892d7b8..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/merge_request_user_mention.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class MergeRequestUserMention < ActiveRecord::Base - self.table_name = 'merge_request_user_mentions' - self.inheritance_column = :_type_disabled - - def self.resource_foreign_key - :merge_request_id - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/namespace.rb b/lib/gitlab/background_migration/user_mentions/models/namespace.rb deleted file mode 100644 index d76d06606ee..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/namespace.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - # isolated Namespace model - class Namespace < ActiveRecord::Base - self.inheritance_column = :_type_disabled - - include Concerns::IsolatedFeatureGate - include Gitlab::BackgroundMigration::UserMentions::Lib::Gitlab::IsolatedVisibilityLevel - include ::Gitlab::Utils::StrongMemoize - include Gitlab::BackgroundMigration::UserMentions::Models::Concerns::Namespace::RecursiveTraversal - - belongs_to :parent, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Namespace" - - def visibility_level_field - :visibility_level - end - - def has_parent? - parent_id.present? || parent.present? - end - - # Deprecated, use #licensed_feature_available? instead. Remove once Namespace#feature_available? isn't used anymore. - def feature_available?(feature) - licensed_feature_available?(feature) - end - - # Overridden in EE::Namespace - def licensed_feature_available?(_feature) - false - end - end - end - end - end -end - -Namespace.prepend_mod_with('Namespace') diff --git a/lib/gitlab/background_migration/user_mentions/models/note.rb b/lib/gitlab/background_migration/user_mentions/models/note.rb deleted file mode 100644 index 4026a91903f..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/note.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/Documentation - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - class Note < ActiveRecord::Base - include EachBatch - include Concerns::IsolatedMentionable - include CacheMarkdownField - - self.table_name = 'notes' - self.inheritance_column = :_type_disabled - - attr_mentionable :note, pipeline: :note - cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true - - belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User" - belongs_to :noteable, polymorphic: true - belongs_to :project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project" - - def for_personal_snippet? - noteable && noteable.instance_of?(PersonalSnippet) - end - - def for_project_noteable? - !for_personal_snippet? && !for_epic? - end - - def skip_project_check? - !for_project_noteable? - end - - def for_epic? - noteable && noteable_type == 'Epic' - end - - def user_mention_resource_id - noteable_id || commit_id - end - - def user_mention_note_id - id - end - - def noteable - super unless for_commit? - end - - def for_commit? - noteable_type == "Commit" - end - - private - - def mentionable_params - return super unless for_epic? - - super.merge(banzai_context_params) - end - - def banzai_context_params - return {} unless noteable - - { group: noteable.group, label_url_method: :group_epics_url } - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/project.rb b/lib/gitlab/background_migration/user_mentions/models/project.rb deleted file mode 100644 index 4e02bf97d12..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/project.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - # isolated Namespace model - class Project < ActiveRecord::Base - include Concerns::IsolatedFeatureGate - include Gitlab::BackgroundMigration::UserMentions::Lib::Gitlab::IsolatedVisibilityLevel - - self.table_name = 'projects' - self.inheritance_column = :_type_disabled - - belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id', class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Group" - belongs_to :namespace, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Namespace" - alias_method :parent, :namespace - - # Returns a collection of projects that is either public or visible to the - # logged in user. - def self.public_or_visible_to_user(user = nil, min_access_level = nil) - min_access_level = nil if user&.can_read_all_resources? - - return public_to_user unless user - - if user.is_a?(::Gitlab::BackgroundMigration::UserMentions::Models::User) - where('EXISTS (?) OR projects.visibility_level IN (?)', - user.authorizations_for_projects(min_access_level: min_access_level), - levels_for_user(user)) - end - end - - def grafana_integration - nil - end - - def default_issues_tracker? - true # we do not care of the issue tracker type(internal or external) when parsing mentions - end - - def visibility_level_field - :visibility_level - end - end - end - end - end -end diff --git a/lib/gitlab/background_migration/user_mentions/models/user.rb b/lib/gitlab/background_migration/user_mentions/models/user.rb deleted file mode 100644 index a30220b6934..00000000000 --- a/lib/gitlab/background_migration/user_mentions/models/user.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BackgroundMigration - module UserMentions - module Models - # isolated Namespace model - class User < ActiveRecord::Base - include Concerns::IsolatedFeatureGate - - self.table_name = 'users' - self.inheritance_column = :_type_disabled - - has_many :project_authorizations, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent - - def authorizations_for_projects(min_access_level: nil, related_project_column: 'projects.id') - authorizations = project_authorizations - .select(1) - .where("project_authorizations.project_id = #{related_project_column}") - - return authorizations unless min_access_level.present? - - authorizations.where('project_authorizations.access_level >= ?', min_access_level) - end - - def can_read_all_resources? - can?(:read_all_resources) - end - - def can?(action, subject = :global) - Ability.allowed?(self, action, subject) - end - end - end - end - end -end |