Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.0KB

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