Class: Jobs::UpdateUsername

Inherits:
Base
  • Object
show all
Defined in:
app/jobs/regular/update_username.rb

Instance Method Summary collapse

Methods inherited from Base

acquire_cluster_concurrency_lock!, clear_cluster_concurrency_lock!, cluster_concurrency, cluster_concurrency_redis_key, delayed_perform, #error_context, get_cluster_concurrency, #last_db_duration, #log, #perform, #perform_immediately

Instance Method Details

#execute(args) ⇒ Object



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
# File 'app/jobs/regular/update_username.rb', line 7

def execute(args)
  @user_id = args[:user_id]
  user = User.find_by(id: @user_id)
  return unless user

  @old_username = args[:old_username].unicode_normalize
  @new_username = args[:new_username].unicode_normalize

  @avatar_img = PrettyText.avatar_img(args[:avatar_template], "tiny")

  @quote_rewriter = QuoteRewriter.new(@user_id)

  @raw_mention_regex =
    /
    (?:
      (?<![\p{Alnum}\p{M}`])     # make sure there is no preceding letter, number or backtick
    )
    @#{@old_username}
    (?:
      (?![\p{Alnum}\p{M}_\-.`])  # make sure there is no trailing letter, number, underscore, dash, dot or backtick
      |                          # or
      (?=[-_.](?:\s|$))          # there is an underscore, dash or dot followed by a whitespace or end of line
    )
  /ix

  cooked_username = PrettyText::Helpers.format_username(@old_username)
  @cooked_mention_username_regex = /\A@#{cooked_username}\z/i
  @cooked_mention_user_path_regex =
    %r{\A/u(?:sers)?/#{UrlHelper.encode_component(cooked_username)}\z}i

  update_posts
  update_revisions
  update_notifications
  update_post_custom_fields

  DiscourseEvent.trigger(:username_changed, @old_username, @new_username)
  DiscourseEvent.trigger(:user_updated, user)
end

#update_notificationsObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'app/jobs/regular/update_username.rb', line 87

def update_notifications
  params = { user_id: @user_id, old_username: @old_username, new_username: @new_username }

  DB.exec(<<~SQL, params)
    UPDATE notifications
    SET data = (data :: JSONB ||
                jsonb_strip_nulls(
                    jsonb_build_object(
                        'original_username', CASE data :: JSONB ->> 'original_username'
                                             WHEN :old_username
                                               THEN :new_username
                                             ELSE NULL END,
                        'display_username', CASE data :: JSONB ->> 'display_username'
                                            WHEN :old_username
                                              THEN :new_username
                                            ELSE NULL END,
                        'username', CASE data :: JSONB ->> 'username'
                                    WHEN :old_username
                                      THEN :new_username
                                    ELSE NULL END,
                        'username2', CASE data :: JSONB ->> 'username2'
                                    WHEN :old_username
                                      THEN :new_username
                                    ELSE NULL END
                    )
                )) :: JSON
    WHERE data ILIKE '%' || :old_username || '%'
  SQL
end

#update_post_custom_fieldsObject



117
118
119
120
121
122
123
# File 'app/jobs/regular/update_username.rb', line 117

def update_post_custom_fields
  DB.exec(<<~SQL, old_username: @old_username, new_username: @new_username)
    UPDATE post_custom_fields
    SET value = :new_username
    WHERE name = 'action_code_who' AND value = :old_username
  SQL
end

#update_postsObject



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
# File 'app/jobs/regular/update_username.rb', line 46

def update_posts
  updated_post_ids = Set.new

  # Other people mentioning this user
  Post
    .with_deleted
    .joins(mentioned("posts.id"))
    .where("a.user_id = :user_id", user_id: @user_id)
    .find_each do |post|
      update_post(post)
      updated_post_ids << post.id
    end

  # User mentioning self (not included in post_actions table)
  Post
    .with_deleted
    .where("raw ILIKE ?", "%@#{@old_username}%")
    .where("posts.user_id = :user_id", user_id: @user_id)
    .find_each do |post|
      update_post(post)
      updated_post_ids << post.id
    end

  Post
    .with_deleted
    .joins(quoted("posts.id"))
    .where("p.user_id = :user_id", user_id: @user_id)
    .find_each { |post| update_post(post) unless updated_post_ids.include?(post.id) }
end

#update_revisionsObject



76
77
78
79
80
81
82
83
84
85
# File 'app/jobs/regular/update_username.rb', line 76

def update_revisions
  PostRevision
    .where("modifications SIMILAR TO ?", "%(raw|cooked)%@#{@old_username}%")
    .find_each { |revision| update_revision(revision) }

  PostRevision
    .joins(quoted("post_revisions.post_id"))
    .where("p.user_id = :user_id", user_id: @user_id)
    .find_each { |revision| update_revision(revision) }
end