1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Bookmark do
11 alias Pleroma.Activity
12 alias Pleroma.Bookmark
13 alias Pleroma.BookmarkFolder
17 @type t :: %__MODULE__{}
20 belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
21 belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
22 belongs_to(:folder, BookmarkFolder, type: FlakeId.Ecto.CompatType)
27 @spec create(Ecto.UUID.t(), Ecto.UUID.t()) ::
28 {:ok, Bookmark.t()} | {:error, Ecto.Changeset.t()}
29 def create(user_id, activity_id, folder_id \\ nil) do
32 activity_id: activity_id,
37 |> cast(attrs, [:user_id, :activity_id, :folder_id])
38 |> validate_required([:user_id, :activity_id])
39 |> unique_constraint(:activity_id, name: :bookmarks_user_id_activity_id_index)
41 on_conflict: [set: [folder_id: folder_id]],
42 conflict_target: [:user_id, :activity_id]
46 @spec for_user_query(Ecto.UUID.t()) :: Ecto.Query.t()
47 def for_user_query(user_id, folder_id \\ nil) do
49 |> where(user_id: ^user_id)
50 |> maybe_filter_by_folder(folder_id)
51 |> join(:inner, [b], activity in assoc(b, :activity))
52 |> preload([b, a], activity: a)
55 defp maybe_filter_by_folder(query, nil), do: query
57 defp maybe_filter_by_folder(query, folder_id) do
59 |> where(folder_id: ^folder_id)
62 def get(user_id, activity_id) do
64 |> where(user_id: ^user_id)
65 |> where(activity_id: ^activity_id)
69 @spec destroy(Ecto.UUID.t(), Ecto.UUID.t()) ::
70 {:ok, Bookmark.t()} | {:error, Ecto.Changeset.t()}
71 def destroy(user_id, activity_id) do
73 where: b.user_id == ^user_id,
74 where: b.activity_id == ^activity_id
80 def set_folder(bookmark, folder_id) do
82 |> cast(%{folder_id: folder_id}, [:folder_id])
83 |> validate_required([:folder_id])