20180413022611_create_missing_namespace_for_internal_users.rb 2.04 KB
Newer Older
1
class CreateMissingNamespaceForInternalUsers < ActiveRecord::Migration[4.2]
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
  DOWNTIME = false

  def up
    connection.exec_query(users_query.to_sql).rows.each do |id, username|
      create_namespace(id, username)
      # When testing locally I've noticed that these internal users are missing
      # the notification email, for more details visit the below link:
      # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18357#note_68327560
      set_notification_email(id)
    end
  end

  def down
    # no-op
  end

  private

  def users
    @users ||= Arel::Table.new(:users)
  end

  def namespaces
    @namespaces ||= Arel::Table.new(:namespaces)
  end

  def users_query
    condition = users[:ghost].eq(true)

    if column_exists?(:users, :support_bot)
      condition = condition.or(users[:support_bot].eq(true))
    end

    users.join(namespaces, Arel::Nodes::OuterJoin)
      .on(namespaces[:type].eq(nil).and(namespaces[:owner_id].eq(users[:id])))
      .where(namespaces[:owner_id].eq(nil))
      .where(condition)
      .project(users[:id], users[:username])
  end

  def create_namespace(user_id, username)
    path = Uniquify.new.string(username) do |str|
      query = "SELECT id FROM namespaces WHERE parent_id IS NULL AND path='#{str}' LIMIT 1"
      connection.exec_query(query).present?
    end

48
    insert_query = "INSERT INTO namespaces(owner_id, path, name, created_at, updated_at) VALUES(#{user_id}, '#{path}', '#{path}', NOW(), NOW())"
49
    namespace_id = connection.insert(insert_query)
50 51 52 53 54 55 56 57 58 59

    create_route(namespace_id)
  end

  def create_route(namespace_id)
    return unless namespace_id

    row = connection.exec_query("SELECT id, path FROM namespaces WHERE id=#{namespace_id}").first
    id, path = row.values_at('id', 'path')

60
    execute("INSERT INTO routes(source_id, source_type, path, name, created_at, updated_at) VALUES(#{id}, 'Namespace', '#{path}', '#{path}', NOW(), NOW())")
61 62 63 64 65 66
  end

  def set_notification_email(user_id)
    execute "UPDATE users SET notification_email = email WHERE notification_email IS NULL AND id = #{user_id}"
  end
end