# Pleroma: A lightweight social networking server # Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Hashtag do use Ecto.Schema import Ecto.Changeset alias Pleroma.Hashtag alias Pleroma.Repo @derive {Jason.Encoder, only: [:data]} schema "hashtags" do field(:name, :string) field(:data, :map, default: %{}) many_to_many(:objects, Pleroma.Object, join_through: "hashtags_objects", on_replace: :delete) timestamps() end def get_by_name(name) do Repo.get_by(Hashtag, name: name) end def get_or_create_by_name(name) when is_bitstring(name) do with %Hashtag{} = hashtag <- get_by_name(name) do {:ok, hashtag} else _ -> %Hashtag{} |> changeset(%{name: name}) |> Repo.insert() end end def get_or_create_by_names(names) when is_list(names) do Enum.reduce_while(names, {:ok, []}, fn name, {:ok, list} -> case get_or_create_by_name(name) do {:ok, %Hashtag{} = hashtag} -> {:cont, {:ok, list ++ [hashtag]}} error -> {:halt, error} end end) end def changeset(%Hashtag{} = struct, params) do struct |> cast(params, [:name, :data]) |> update_change(:name, &String.downcase/1) |> validate_required([:name]) |> unique_constraint(:name) end end