move to 2.5.5
[anni] / priv / repo / migrations / 20191009154608_copy_users_info_fields_to_users.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Repo.Migrations.CopyUsersInfoFieldsToUsers do
6   use Ecto.Migration
7
8   @jsonb_array_default "'[]'::jsonb"
9
10   @info_fields [
11     :banner,
12     :background,
13     :source_data,
14     :note_count,
15     :follower_count,
16     :following_count,
17     :locked,
18     :confirmation_pending,
19     :password_reset_pending,
20     :confirmation_token,
21     :default_scope,
22     :blocks,
23     :domain_blocks,
24     :mutes,
25     :muted_reblogs,
26     :muted_notifications,
27     :subscribers,
28     :deactivated,
29     :no_rich_text,
30     :ap_enabled,
31     :is_moderator,
32     :is_admin,
33     :show_role,
34     :settings,
35     :magic_key,
36     :uri,
37     :hide_followers_count,
38     :hide_follows_count,
39     :hide_followers,
40     :hide_follows,
41     :hide_favorites,
42     :unread_conversation_count,
43     :pinned_activities,
44     :email_notifications,
45     :mascot,
46     :emoji,
47     :pleroma_settings_store,
48     :fields,
49     :raw_fields,
50     :discoverable,
51     :invisible,
52     :skip_thread_containment,
53     :notification_settings
54   ]
55
56   @jsonb_fields [
57     :banner,
58     :background,
59     :source_data,
60     :settings,
61     :email_notifications,
62     :mascot,
63     :pleroma_settings_store,
64     :notification_settings
65   ]
66
67   @array_jsonb_fields [:emoji, :fields, :raw_fields]
68
69   @int_fields [:note_count, :follower_count, :following_count, :unread_conversation_count]
70
71   @boolean_fields [
72     :locked,
73     :confirmation_pending,
74     :password_reset_pending,
75     :deactivated,
76     :no_rich_text,
77     :ap_enabled,
78     :is_moderator,
79     :is_admin,
80     :show_role,
81     :hide_followers_count,
82     :hide_follows_count,
83     :hide_followers,
84     :hide_follows,
85     :hide_favorites,
86     :discoverable,
87     :invisible,
88     :skip_thread_containment
89   ]
90
91   @array_text_fields [
92     :blocks,
93     :domain_blocks,
94     :mutes,
95     :muted_reblogs,
96     :muted_notifications,
97     :subscribers,
98     :pinned_activities
99   ]
100
101   def change do
102     if direction() == :up do
103       sets =
104         for f <- @info_fields do
105           set_field = "#{f} ="
106
107           # Coercion of null::jsonb to NULL
108           jsonb = "case when info->>'#{f}' IS NULL then null else info->'#{f}' end"
109
110           cond do
111             f in @jsonb_fields ->
112               "#{set_field} #{jsonb}"
113
114             f in @array_jsonb_fields ->
115               "#{set_field} coalesce(#{jsonb}, #{@jsonb_array_default})"
116
117             f in @int_fields ->
118               "#{set_field} (info->>'#{f}')::int"
119
120             f in @boolean_fields ->
121               "#{set_field} coalesce((info->>'#{f}')::boolean, false)"
122
123             f in @array_text_fields ->
124               "#{set_field} ARRAY(SELECT jsonb_array_elements_text(#{jsonb}))"
125
126             true ->
127               "#{set_field} info->>'#{f}'"
128           end
129         end
130         |> Enum.join(", ")
131
132       execute("update users set " <> sets)
133
134       for index_name <- [
135             :users_deactivated_index,
136             :users_is_moderator_index,
137             :users_is_admin_index,
138             :users_subscribers_index
139           ] do
140         drop_if_exists(index(:users, [], name: index_name))
141       end
142     end
143
144     create_if_not_exists(index(:users, [:deactivated]))
145     create_if_not_exists(index(:users, [:is_moderator]))
146     create_if_not_exists(index(:users, [:is_admin]))
147     create_if_not_exists(index(:users, [:subscribers]))
148   end
149 end