diff options
-rw-r--r-- | lib/pleroma/chat/message_reference.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/delivery.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/hashtag.ex | 5 | ||||
-rw-r--r-- | lib/pleroma/hashtag_object.ex | 17 | ||||
-rw-r--r-- | lib/pleroma/migrators/hashtags_table_migrator.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/object.ex | 5 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/object_validators/common_fields.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/schemas/status.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 14 | ||||
-rw-r--r-- | priv/repo/migrations/20211218181632_change_object_id_to_flake.exs | 43 | ||||
-rw-r--r-- | test/pleroma/pagination_test.exs | 10 |
12 files changed, 94 insertions, 20 deletions
diff --git a/lib/pleroma/chat/message_reference.ex b/lib/pleroma/chat/message_reference.ex index 89537d155..06fdb3401 100644 --- a/lib/pleroma/chat/message_reference.ex +++ b/lib/pleroma/chat/message_reference.ex @@ -20,7 +20,7 @@ defmodule Pleroma.Chat.MessageReference do @primary_key {:id, FlakeId.Ecto.Type, autogenerate: true} schema "chat_message_references" do - belongs_to(:object, Object) + belongs_to(:object, Object, type: FlakeId.Ecto.CompatType) belongs_to(:chat, Chat, type: FlakeId.Ecto.CompatType) field(:unread, :boolean, default: true) diff --git a/lib/pleroma/delivery.ex b/lib/pleroma/delivery.ex index 511d5cf58..b1ed6a8fd 100644 --- a/lib/pleroma/delivery.ex +++ b/lib/pleroma/delivery.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Delivery do schema "deliveries" do belongs_to(:user, User, type: FlakeId.Ecto.CompatType) - belongs_to(:object, Object) + belongs_to(:object, Object, type: FlakeId.Ecto.CompatType) end def changeset(delivery, params \\ %{}) do diff --git a/lib/pleroma/hashtag.ex b/lib/pleroma/hashtag.ex index 53e2e9c89..046c67943 100644 --- a/lib/pleroma/hashtag.ex +++ b/lib/pleroma/hashtag.ex @@ -10,13 +10,14 @@ defmodule Pleroma.Hashtag do alias Ecto.Multi alias Pleroma.Hashtag + alias Pleroma.HashtagObject alias Pleroma.Object alias Pleroma.Repo schema "hashtags" do field(:name, :string) - many_to_many(:objects, Object, join_through: "hashtags_objects", on_replace: :delete) + many_to_many(:objects, Object, join_through: HashtagObject, on_replace: :delete) timestamps() end @@ -80,7 +81,7 @@ defmodule Pleroma.Hashtag do def unlink(%Object{id: object_id}) do with {_, hashtag_ids} <- - from(hto in "hashtags_objects", + from(hto in HashtagObject, where: hto.object_id == ^object_id, select: hto.hashtag_id ) diff --git a/lib/pleroma/hashtag_object.ex b/lib/pleroma/hashtag_object.ex new file mode 100644 index 000000000..12b570715 --- /dev/null +++ b/lib/pleroma/hashtag_object.ex @@ -0,0 +1,17 @@ +defmodule Pleroma.HashtagObject do + @moduledoc """ + Through table relationship between hashtags and objects. + https://hexdocs.pm/ecto/polymorphic-associations-with-many-to-many.html + """ + use Ecto.Schema + + alias Pleroma.Hashtag + alias Pleroma.Object + + @primary_key false + + schema "hashtags_objects" do + belongs_to(:hashtag, Hashtag) + belongs_to(:object, Object, type: FlakeId.Ecto.CompatType) + end +end diff --git a/lib/pleroma/migrators/hashtags_table_migrator.ex b/lib/pleroma/migrators/hashtags_table_migrator.ex index b84058e11..3b8170c9f 100644 --- a/lib/pleroma/migrators/hashtags_table_migrator.ex +++ b/lib/pleroma/migrators/hashtags_table_migrator.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do use Pleroma.Migrators.Support.BaseMigrator alias Pleroma.Hashtag + alias Pleroma.HashtagObject alias Pleroma.Migrators.Support.BaseMigrator alias Pleroma.Object @@ -120,7 +121,7 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do try do with {rows_count, _} when is_integer(rows_count) <- - Repo.insert_all("hashtags_objects", maps, on_conflict: :nothing) do + Repo.insert_all(HashtagObject, maps, on_conflict: :nothing) do object.id else e -> diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index c3ea1b98b..8569fed8c 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Object do alias Pleroma.Activity alias Pleroma.Config alias Pleroma.Hashtag + alias Pleroma.HashtagObject alias Pleroma.Object alias Pleroma.Object.Fetcher alias Pleroma.ObjectTombstone @@ -22,6 +23,8 @@ defmodule Pleroma.Object do @type t() :: %__MODULE__{} + @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} + @derive {Jason.Encoder, only: [:data]} @cachex Pleroma.Config.get([:cachex, :provider], Cachex) @@ -29,7 +32,7 @@ defmodule Pleroma.Object do schema "objects" do field(:data, :map) - many_to_many(:hashtags, Hashtag, join_through: "hashtags_objects", on_replace: :delete) + many_to_many(:hashtags, Hashtag, join_through: HashtagObject, on_replace: :delete) timestamps() end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 8324ca22c..9f51a3062 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do alias Pleroma.Conversation.Participation alias Pleroma.Filter alias Pleroma.Hashtag + alias Pleroma.HashtagObject alias Pleroma.Maps alias Pleroma.Notification alias Pleroma.Object @@ -775,8 +776,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_embedded_tag_reject_any(query, _), do: query defp object_ids_query_for_tags(tags) do - from(hto in "hashtags_objects") - |> join(:inner, [hto], ht in Pleroma.Hashtag, on: hto.hashtag_id == ht.id) + from(hto in HashtagObject) + |> join(:inner, [hto], ht in Hashtag, on: hto.hashtag_id == ht.id) |> where([hto, ht], ht.name in ^tags) |> select([hto], hto.object_id) |> distinct([hto], true) @@ -825,7 +826,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do # Note: NO extra ordering should be done on "activities.id desc nulls last" for optimal plan from( [_activity, object] in query, - join: hto in "hashtags_objects", + join: hto in HashtagObject, on: hto.object_id == object.id, where: hto.hashtag_id in ^hashtag_ids, distinct: [desc: object.id], diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex index 872f80ec3..cb1f4e144 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex @@ -52,7 +52,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do field(:context, :string) # short identifier for PleromaFE to group statuses by context - field(:context_id, :integer) + field(:context_id, :string) field(:sensitive, :boolean, default: false) field(:replies_count, :integer, default: 0) diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex index 3d042dc19..a12777068 100644 --- a/lib/pleroma/web/api_spec/schemas/status.ex +++ b/lib/pleroma/web/api_spec/schemas/status.ex @@ -143,7 +143,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do "A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`" }, conversation_id: %Schema{ - type: :integer, + type: :string, description: "The ID of the AP context the status is associated with (if any)" }, direct_conversation_id: %Schema{ @@ -317,7 +317,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do "pinned" => false, "pleroma" => %{ "content" => %{"text/plain" => "foobar"}, - "conversation_id" => 345_972, + "conversation_id" => "AEXFhY7X4zd8hZK8oK", "direct_conversation_id" => nil, "emoji_reactions" => [], "expires_at" => nil, diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 463f34198..ce350ad23 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -57,11 +57,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end) end - defp get_context_id(%{data: %{"context_id" => context_id}}) when not is_nil(context_id), + defp get_context_id(%{data: %{"context_id" => context_id}}) when is_binary(context_id), do: context_id - defp get_context_id(%{data: %{"context" => context}}) when is_binary(context), - do: Utils.context_to_conversation_id(context) + defp get_context_id(%{data: %{"context_id" => context_id}}) when is_integer(context_id), + do: to_string(context_id) + + defp get_context_id(%{data: %{"context" => context}}) when is_binary(context) do + case Utils.context_to_conversation_id(context) do + id when is_binary(id) -> id + id when is_integer(id) -> to_string(id) + _ -> nil + end + end defp get_context_id(_), do: nil diff --git a/priv/repo/migrations/20211218181632_change_object_id_to_flake.exs b/priv/repo/migrations/20211218181632_change_object_id_to_flake.exs new file mode 100644 index 000000000..3eebe3ef2 --- /dev/null +++ b/priv/repo/migrations/20211218181632_change_object_id_to_flake.exs @@ -0,0 +1,43 @@ +defmodule Pleroma.Repo.Migrations.ChangeObjectIdToFlake do + @moduledoc """ + Convert object IDs to FlakeIds. + Fortunately only a few tables have a foreign key to objects. Update them. + """ + use Ecto.Migration + + def up do + # Switch object IDs to FlakeIds + execute(""" + alter table objects + drop constraint objects_pkey cascade, + alter column id drop default, + alter column id set data type uuid using cast( lpad( to_hex(id), 32, '0') as uuid), + add primary key (id) + """) + + # Update chat message foreign key + execute(""" + alter table chat_message_references + alter column object_id set data type uuid using cast( lpad( to_hex(object_id), 32, '0') as uuid), + add constraint chat_message_references_object_id_fkey foreign key (object_id) references objects(id) on delete cascade + """) + + # Update delivery foreign key + execute(""" + alter table deliveries + alter column object_id set data type uuid using cast( lpad( to_hex(object_id), 32, '0') as uuid), + add constraint deliveries_object_id_fkey foreign key (object_id) references objects(id) + """) + + # Update hashtag many-to-many foreign key + execute(""" + alter table hashtags_objects + alter column object_id set data type uuid using cast( lpad( to_hex(object_id), 32, '0') as uuid), + add constraint hashtags_objects_object_id_fkey foreign key (object_id) references objects(id) on delete cascade + """) + end + + def down do + :ok + end +end diff --git a/test/pleroma/pagination_test.exs b/test/pleroma/pagination_test.exs index bc26c8b46..6e5c767e6 100644 --- a/test/pleroma/pagination_test.exs +++ b/test/pleroma/pagination_test.exs @@ -18,7 +18,7 @@ defmodule Pleroma.PaginationTest do end test "paginates by min_id", %{notes: notes} do - id = Enum.at(notes, 2).id |> Integer.to_string() + id = Enum.at(notes, 2).id %{total: total, items: paginated} = Pagination.fetch_paginated(Object, %{min_id: id, total: true}) @@ -28,7 +28,7 @@ defmodule Pleroma.PaginationTest do end test "paginates by since_id", %{notes: notes} do - id = Enum.at(notes, 2).id |> Integer.to_string() + id = Enum.at(notes, 2).id %{total: total, items: paginated} = Pagination.fetch_paginated(Object, %{since_id: id, total: true}) @@ -38,7 +38,7 @@ defmodule Pleroma.PaginationTest do end test "paginates by max_id", %{notes: notes} do - id = Enum.at(notes, 1).id |> Integer.to_string() + id = Enum.at(notes, 1).id %{total: total, items: paginated} = Pagination.fetch_paginated(Object, %{max_id: id, total: true}) @@ -48,7 +48,7 @@ defmodule Pleroma.PaginationTest do end test "paginates by min_id & limit", %{notes: notes} do - id = Enum.at(notes, 2).id |> Integer.to_string() + id = Enum.at(notes, 2).id paginated = Pagination.fetch_paginated(Object, %{min_id: id, limit: 1}) @@ -56,7 +56,7 @@ defmodule Pleroma.PaginationTest do end test "handles id gracefully", %{notes: notes} do - id = Enum.at(notes, 1).id |> Integer.to_string() + id = Enum.at(notes, 1).id paginated = Pagination.fetch_paginated(Object, %{ |