logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

20191118084500_data_migration_populate_user_relationships.exs (2161B)


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