Add option to modify HTTP pool size
[akkoma] / priv / repo / migrations / 20191118084500_data_migration_populate_user_relationships.exs
1 defmodule Pleroma.Repo.Migrations.DataMigrationPopulateUserRelationships do
2 use Ecto.Migration
3
4 alias Ecto.Adapters.SQL
5 alias Pleroma.Repo
6
7 require Logger
8
9 def up do
10 Enum.each(
11 [blocks: 1, mutes: 2, muted_reblogs: 3, muted_notifications: 4, subscribers: 5],
12 fn {field, relationship_type_code} ->
13 migrate(field, relationship_type_code)
14
15 if field == :subscribers do
16 drop_if_exists(index(:users, [:subscribers]))
17 end
18 end
19 )
20 end
21
22 def down, do: :noop
23
24 defp migrate(field, relationship_type_code) do
25 Logger.info("Processing users.#{field}...")
26
27 {:ok, %{rows: field_rows}} =
28 SQL.query(Repo, "SELECT id, #{field} FROM users WHERE #{field} != '{}'")
29
30 target_ap_ids =
31 Enum.flat_map(
32 field_rows,
33 fn [_, ap_ids] -> ap_ids end
34 )
35 |> Enum.uniq()
36
37 # Selecting ids of all targets at once in order to reduce the number of SELECT queries
38 {:ok, %{rows: target_ap_id_id}} =
39 SQL.query(Repo, "SELECT ap_id, id FROM users WHERE ap_id = ANY($1)", [target_ap_ids])
40
41 target_id_by_ap_id = Enum.into(target_ap_id_id, %{}, fn [k, v] -> {k, v} end)
42
43 Enum.each(
44 field_rows,
45 fn [source_id, target_ap_ids] ->
46 source_uuid = Ecto.UUID.cast!(source_id)
47
48 for target_ap_id <- target_ap_ids do
49 target_id = target_id_by_ap_id[target_ap_id]
50
51 with {:ok, target_uuid} <- target_id && Ecto.UUID.cast(target_id) do
52 execute("""
53 INSERT INTO user_relationships(
54 source_id, target_id, relationship_type, inserted_at
55 )
56 VALUES(
57 '#{source_uuid}'::uuid, '#{target_uuid}'::uuid, #{relationship_type_code}, now()
58 )
59 ON CONFLICT (source_id, relationship_type, target_id) DO NOTHING
60 """)
61 else
62 _ -> Logger.warn("Unresolved #{field} reference: (#{source_uuid}, #{target_id})")
63 end
64 end
65 end
66 )
67 end
68 end