diff options
author | Alex Gleason <alex@alexgleason.me> | 2021-12-29 15:42:34 -0600 |
---|---|---|
committer | Alex Gleason <alex@alexgleason.me> | 2021-12-29 15:42:34 -0600 |
commit | 032aa8895fe27a7b8d3976a295cea05930e2e953 (patch) | |
tree | 5d1a65f3ac3b982a41533db3dab8e62c3734f352 | |
parent | aedf47c45fa3d39e5da671bbc1ded1bcf055794e (diff) | |
download | pleroma-032aa8895fe27a7b8d3976a295cea05930e2e953.tar.gz |
Add LegacyActivity module for old migrations
3 files changed, 107 insertions, 3 deletions
diff --git a/lib/pleroma/migration_helper/legacy_activity.ex b/lib/pleroma/migration_helper/legacy_activity.ex new file mode 100644 index 000000000..0ba071424 --- /dev/null +++ b/lib/pleroma/migration_helper/legacy_activity.ex @@ -0,0 +1,103 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.MigrationHelper.LegacyActivity do + @moduledoc """ + Legacy "activities" schema needed for old migrations. + """ + use Ecto.Schema + + alias Pleroma.Activity.Queries + alias Pleroma.Bookmark + alias Pleroma.MigrationHelper.LegacyActivity, as: Activity + alias Pleroma.Notification + alias Pleroma.Object + alias Pleroma.Repo + alias Pleroma.ReportNote + alias Pleroma.User + + import Ecto.Query + + @type t :: %__MODULE__{} + @type actor :: String.t() + + @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} + + schema "activities" do + field(:data, :map) + field(:local, :boolean, default: true) + field(:actor, :string) + field(:recipients, {:array, :string}, default: []) + field(:thread_muted?, :boolean, virtual: true) + + # A field that can be used if you need to join some kind of other + # id to order / paginate this field by + field(:pagination_id, :string, virtual: true) + + # This is a fake relation, + # do not use outside of with_preloaded_user_actor/with_joined_user_actor + has_one(:user_actor, User, on_delete: :nothing, foreign_key: :id) + # This is a fake relation, do not use outside of with_preloaded_bookmark/get_bookmark + has_one(:bookmark, Bookmark, foreign_key: :activity_id) + # This is a fake relation, do not use outside of with_preloaded_report_notes + has_many(:report_notes, ReportNote, foreign_key: :activity_id) + has_many(:notifications, Notification, on_delete: :delete_all, foreign_key: :activity_id) + + # Attention: this is a fake relation, don't try to preload it blindly and expect it to work! + # The foreign key is embedded in a jsonb field. + # + # To use it, you probably want to do an inner join and a preload: + # + # ``` + # |> join(:inner, [activity], o in Object, + # on: fragment("(?->>'id') = COALESCE((?)->'object'->> 'id', (?)->>'object')", + # o.data, activity.data, activity.data)) + # |> preload([activity, object], [object: object]) + # ``` + # + # As a convenience, Activity.with_preloaded_object() sets up an inner join and preload for the + # typical case. + has_one(:object, Object, on_delete: :nothing, foreign_key: :id) + + timestamps() + end + + def with_joined_object(query, join_type \\ :inner) do + join(query, join_type, [activity], o in Object, + on: + fragment( + "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')", + o.data, + activity.data, + activity.data + ), + as: :object + ) + end + + def with_preloaded_object(query, join_type \\ :inner) do + query + |> has_named_binding?(:object) + |> if(do: query, else: with_joined_object(query, join_type)) + |> preload([activity, object: object], object: object) + end + + def all_by_ids_with_object(ids) do + Activity + |> where([a], a.id in ^ids) + |> with_preloaded_object() + |> Repo.all() + end + + @doc """ + Accepts `ap_id` or list of `ap_id`. + Returns a query. + """ + @spec create_by_object_ap_id(String.t() | [String.t()]) :: Ecto.Queryable.t() + def create_by_object_ap_id(ap_id) do + ap_id + |> Queries.by_object_id() + |> Queries.by_type("Create") + end +end diff --git a/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs b/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs index b6f0ac66b..cbc9884a5 100644 --- a/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs +++ b/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs @@ -1,8 +1,8 @@ defmodule Pleroma.Repo.Migrations.MigrateOldBookmarks do use Ecto.Migration import Ecto.Query - alias Pleroma.Activity alias Pleroma.Bookmark + alias Pleroma.MigrationHelper.LegacyActivity alias Pleroma.Repo def up do @@ -18,7 +18,7 @@ defmodule Pleroma.Repo.Migrations.MigrateOldBookmarks do Enum.each(bookmarks, fn ap_id -> activity = ap_id - |> Activity.create_by_object_ap_id() + |> LegacyActivity.create_by_object_ap_id() |> Repo.one() unless is_nil(activity), do: {:ok, _} = Bookmark.create(user_id, activity.id) diff --git a/priv/repo/migrations/20210205145000_move_pinned_activities_into_pinned_objects.exs b/priv/repo/migrations/20210205145000_move_pinned_activities_into_pinned_objects.exs index 9aee545e3..a6dd886bf 100644 --- a/priv/repo/migrations/20210205145000_move_pinned_activities_into_pinned_objects.exs +++ b/priv/repo/migrations/20210205145000_move_pinned_activities_into_pinned_objects.exs @@ -3,6 +3,7 @@ defmodule Pleroma.Repo.Migrations.MovePinnedActivitiesIntoPinnedObjects do import Ecto.Query + alias Pleroma.MigrationHelper.LegacyActivity alias Pleroma.Repo alias Pleroma.User @@ -11,7 +12,7 @@ defmodule Pleroma.Repo.Migrations.MovePinnedActivitiesIntoPinnedObjects do |> select([u], {u.id, fragment("?.pinned_activities", u)}) |> Repo.stream() |> Stream.each(fn {user_id, pinned_activities_ids} -> - pinned_activities = Pleroma.Activity.all_by_ids_with_object(pinned_activities_ids) + pinned_activities = LegacyActivity.all_by_ids_with_object(pinned_activities_ids) pins = Map.new(pinned_activities, fn %{object: %{data: %{"id" => object_id}}} -> |