defmodule Mobilizon.Tombstone do @moduledoc """ Represent tombstones for deleted objects. Saves only URI """ use Ecto.Schema import Ecto.Changeset alias Mobilizon.Actors.Actor alias Mobilizon.Storage.Repo require Ecto.Query @type t :: %__MODULE__{ uri: String.t(), actor: Actor.t() } @required_attrs [:uri, :actor_id] @optional_attrs [] @attrs @required_attrs ++ @optional_attrs schema "tombstones" do field(:uri, :string) belongs_to(:actor, Actor) timestamps() end @doc false @spec changeset(t | Ecto.Schema.t(), map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = tombstone, attrs) do tombstone |> cast(attrs, @attrs) |> validate_required(@required_attrs) end @spec create_tombstone(map) :: {:ok, t()} | {:error, Ecto.Changeset.t()} def create_tombstone(attrs) do %__MODULE__{} |> changeset(attrs) |> Repo.insert(on_conflict: :replace_all, conflict_target: :uri) end @spec find_tombstone(String.t()) :: t() | nil def find_tombstone(uri) do __MODULE__ |> Ecto.Query.where([t], t.uri == ^uri) |> Ecto.Query.preload([t], [:actor]) |> Repo.one() end @spec delete_actor_tombstones(String.t() | integer()) :: {integer(), nil} def delete_actor_tombstones(actorId) do __MODULE__ |> Ecto.Query.where(actor_id: ^actorId) |> Repo.delete_all() end @spec delete_uri_tombstone(String.t()) :: {integer(), nil} def delete_uri_tombstone(uri) do __MODULE__ |> Ecto.Query.where(uri: ^uri) |> Repo.delete_all() end end