20191118084500_data_migration_populate_user_relationships.exs (2161B)
- # Pleroma: A lightweight social networking server
- # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
- # SPDX-License-Identifier: AGPL-3.0-only
- defmodule Pleroma.Repo.Migrations.DataMigrationPopulateUserRelationships do
- use Ecto.Migration
- alias Ecto.Adapters.SQL
- alias Pleroma.Repo
- require Logger
- def up do
- Enum.each(
- [blocks: 1, mutes: 2, muted_reblogs: 3, muted_notifications: 4, subscribers: 5],
- fn {field, relationship_type_code} ->
- migrate(field, relationship_type_code)
- if field == :subscribers do
- drop_if_exists(index(:users, [:subscribers]))
- end
- end
- )
- end
- def down, do: :noop
- defp migrate(field, relationship_type_code) do
- Logger.info("Processing users.#{field}...")
- {:ok, %{rows: field_rows}} =
- SQL.query(Repo, "SELECT id, #{field} FROM users WHERE #{field} != '{}'")
- target_ap_ids =
- Enum.flat_map(
- field_rows,
- fn [_, ap_ids] -> ap_ids end
- )
- |> Enum.uniq()
- # Selecting ids of all targets at once in order to reduce the number of SELECT queries
- {:ok, %{rows: target_ap_id_id}} =
- SQL.query(Repo, "SELECT ap_id, id FROM users WHERE ap_id = ANY($1)", [target_ap_ids])
- target_id_by_ap_id = Enum.into(target_ap_id_id, %{}, fn [k, v] -> {k, v} end)
- Enum.each(
- field_rows,
- fn [source_id, target_ap_ids] ->
- source_uuid = Ecto.UUID.cast!(source_id)
- for target_ap_id <- target_ap_ids do
- target_id = target_id_by_ap_id[target_ap_id]
- with {:ok, target_uuid} <- target_id && Ecto.UUID.cast(target_id) do
- execute("""
- INSERT INTO user_relationships(
- source_id, target_id, relationship_type, inserted_at
- )
- VALUES(
- '#{source_uuid}'::uuid, '#{target_uuid}'::uuid, #{relationship_type_code}, now()
- )
- ON CONFLICT (source_id, relationship_type, target_id) DO NOTHING
- """)
- else
- _ -> Logger.warning("Unresolved #{field} reference: (#{source_uuid}, #{target_id})")
- end
- end
- end
- )
- end
- end