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

20200703064117_generate_missing_routes_for_bots.rb « post_migrate « db - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1d3f57d3fe61dbcba5c792660e99dbbd7c65fd2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# frozen_string_literal: true

class GenerateMissingRoutesForBots < ActiveRecord::Migration[6.0]
  DOWNTIME = false

  disable_ddl_transaction!

  class User < ActiveRecord::Base
    self.table_name = 'users'

    USER_TYPES = {
      human: nil,
      support_bot: 1,
      alert_bot: 2,
      visual_review_bot: 3,
      service_user: 4,
      ghost: 5,
      project_bot: 6,
      migration_bot: 7
    }.with_indifferent_access.freeze

    BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot].freeze

    scope :bots, -> { where(user_type: USER_TYPES.values_at(*BOT_USER_TYPES)) }
  end

  class Route < ActiveRecord::Base
    self.table_name = 'routes'

    validates :path,
      uniqueness: { case_sensitive: false }
  end

  class Namespace < ActiveRecord::Base
    self.table_name = 'namespaces'

    belongs_to :owner, class_name: 'GenerateMissingRoutesForBots::User'

    scope :for_user, -> { where(type: nil) }
    scope :for_bots, -> { for_user.joins(:owner).merge(GenerateMissingRoutesForBots::User.bots) }

    scope :without_routes, -> do
      where(
        'NOT EXISTS (
          SELECT 1
          FROM routes
          WHERE source_type = ?
          AND source_id = namespaces.id
        )',
          self.source_type_for_route
      )
    end

    def self.source_type_for_route
      'Namespace'
    end

    def attributes_for_insert
      {
        source_type: self.class.source_type_for_route,
        source_id: id,
        name: name,
        path: path
      }
    end
  end

  def up
    # Reset the column information of all the models that update the database
    # to ensure the Active Record's knowledge of the table structure is current
    Route.reset_column_information

    logger = Gitlab::BackgroundMigration::Logger.build
    attributes_to_be_logged = %w(id path name)

    GenerateMissingRoutesForBots::Namespace.for_bots.without_routes.each do |namespace|
      route = GenerateMissingRoutesForBots::Route.create(namespace.attributes_for_insert)
      namespace_details = namespace.as_json.slice(*attributes_to_be_logged)

      if route.persisted?
        logger.info namespace_details.merge(message: 'a new route was created for the namespace')
      else
        errors = route.errors.full_messages.join(',')
        logger.info namespace_details.merge(message: 'route creation failed for the namespace', errors: errors)
      end
    end
  end

  def down
    # no op
  end
end