1 defmodule Pleroma.Repo.Migrations.CreateFollowingRelationships do
4 # had to disable these to be able to restore `following` index concurrently
5 # https://hexdocs.pm/ecto_sql/Ecto.Migration.html#index/3-adding-dropping-indexes-concurrently
6 @disable_ddl_transaction true
7 @disable_migration_lock true
10 create_if_not_exists table(:following_relationships) do
11 add(:follower_id, references(:users, type: :uuid, on_delete: :delete_all), null: false)
12 add(:following_id, references(:users, type: :uuid, on_delete: :delete_all), null: false)
13 add(:state, :string, null: false)
18 create_if_not_exists(index(:following_relationships, :follower_id))
19 create_if_not_exists(unique_index(:following_relationships, [:follower_id, :following_id]))
21 execute(import_following_from_users(), "")
22 execute(import_following_from_activities(), restore_following_column())
24 drop(index(:users, [:following], concurrently: true, using: :gin))
26 alter table(:users) do
27 remove(:following, {:array, :string}, default: [])
31 defp import_following_from_users do
33 INSERT INTO following_relationships (follower_id, following_id, state, inserted_at, updated_at)
35 relations.follower_id,
42 users.id AS follower_id,
43 unnest(users.following) AS following_ap_id
47 users.following != '{}'
48 AND users.local = false OR users.local = true AND users.email IS NOT NULL -- Exclude `internal/fetch` and `relay`
50 JOIN users AS "following" ON "following".follower_address = relations.following_ap_id
52 WHERE relations.follower_id != following.id
53 ON CONFLICT DO NOTHING
57 defp import_following_from_activities do
60 following_relationships (
70 activities.data ->> 'state',
71 (activities.data ->> 'published') :: timestamp,
75 JOIN users AS followers ON (activities.actor = followers.ap_id)
76 JOIN users AS following ON (activities.data ->> 'object' = following.ap_id)
78 activities.data ->> 'type' = 'Follow'
79 AND activities.data ->> 'state' IN ('accept', 'pending', 'reject')
80 ORDER BY activities.updated_at DESC
81 ON CONFLICT DO NOTHING
85 defp restore_following_column do
90 following = following_query.following_array,
94 follwer.id AS follower_id,
97 array_prepend(follwer.follower_address, array_agg(following.follower_address))
99 array_agg(following.follower_address)
100 END AS following_array
102 following_relationships
103 JOIN users AS follwer ON follwer.id = following_relationships.follower_id
104 JOIN users AS FOLLOWING ON following.id = following_relationships.following_id
106 follwer.id) AS following_query
108 following_query.follower_id = users.id