diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 572c32a32..bea93ecda 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -19,14 +19,21 @@ defmodule Pleroma.Object do schema "objects" do field(:data, :map) + # This is set by a database side trigger on insert and update field(:ap_id, :string) timestamps() end + # Add the default 'returning' options, so we get the generated ap_id column + def insert(cng, options \\ []) do + cng + |> Repo.insert(Keyword.put(options, :returning, true)) + end + def create(data) do Object.change(%Object{}, %{data: data}) - |> Repo.insert() + |> insert() end def change(struct, params \\ %{}) do diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 984f85cc6..49cb18831 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -976,7 +976,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do data end - Repo.insert(%Object{data: obj_data}) + Object.insert(%Object{data: obj_data}) end end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 39a532db3..27f9c5ab4 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -153,7 +153,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do with true <- is_nil(object), changeset <- Object.context_mapping(context), - {:ok, inserted_object} <- Repo.insert(changeset) do + {:ok, inserted_object} <- Object.insert(changeset) do inserted_object else _ -> diff --git a/priv/repo/migrations/20191007123056_add_ap_id_column_to_objects.exs b/priv/repo/migrations/20191007123056_add_ap_id_column_to_objects.exs index ebc94833c..fb38fa29c 100644 --- a/priv/repo/migrations/20191007123056_add_ap_id_column_to_objects.exs +++ b/priv/repo/migrations/20191007123056_add_ap_id_column_to_objects.exs @@ -6,6 +6,6 @@ defmodule Pleroma.Repo.Migrations.AddApIdColumnToObjects do add :ap_id, :string end - create unique_index(:objects, [:ap_id], concurrently: true) + create unique_index(:objects, [:ap_id]) end end diff --git a/priv/repo/migrations/20191007160755_fill_object_ap_id_field.exs b/priv/repo/migrations/20191007160755_fill_object_ap_id_field.exs new file mode 100644 index 000000000..55834b3e1 --- /dev/null +++ b/priv/repo/migrations/20191007160755_fill_object_ap_id_field.exs @@ -0,0 +1,7 @@ +defmodule Pleroma.Repo.Migrations.FillObjectApIdField do + use Ecto.Migration + + def change do + execute("update objects set ap_id = data->>'id'") + end +end diff --git a/priv/repo/migrations/20191007170423_add_object_ap_id_trigger.exs b/priv/repo/migrations/20191007170423_add_object_ap_id_trigger.exs new file mode 100644 index 000000000..99ffa79e6 --- /dev/null +++ b/priv/repo/migrations/20191007170423_add_object_ap_id_trigger.exs @@ -0,0 +1,25 @@ +defmodule Pleroma.Repo.Migrations.AddObjectApIdTrigger do + use Ecto.Migration + + def change do + execute(""" + CREATE OR REPLACE FUNCTION set_ap_id() + RETURNS trigger + LANGUAGE plpgsql + AS $BODY$ + BEGIN + NEW.ap_id = NEW.data->>'id'; + RETURN NEW; + END + $BODY$; + """) + + execute(""" + CREATE TRIGGER object_ap_id_extraction + BEFORE INSERT OR UPDATE + ON objects + FOR EACH ROW + EXECUTE PROCEDURE set_ap_id(); + """) + end +end diff --git a/test/object_test.exs b/test/object_test.exs index 3d64fdb49..ed62f6485 100644 --- a/test/object_test.exs +++ b/test/object_test.exs @@ -19,6 +19,7 @@ defmodule Pleroma.ObjectTest do test "returns an object by it's AP id" do object = insert(:note) + object = Object.get_by_id(object.id) found_object = Object.get_by_ap_id(object.data["id"]) assert object == found_object @@ -32,11 +33,21 @@ defmodule Pleroma.ObjectTest do {:error, _result} = Repo.insert(cs) end + + test "it automatically sets the ap_id field" do + {:ok, object} = + %Object{} + |> Object.change(%{data: %{id: "myid"}}) + |> Object.insert() + + assert object.ap_id == "myid" + end end describe "deletion function" do test "deletes an object" do object = insert(:note) + object = Object.get_by_id(object.id) found_object = Object.get_by_ap_id(object.data["id"]) assert object == found_object @@ -52,6 +63,7 @@ defmodule Pleroma.ObjectTest do test "ensures cache is cleared for the object" do object = insert(:note) + object = Object.get_by_id(object.id) cached_object = Object.get_cached_by_ap_id(object.data["id"]) assert object == cached_object