# Pleroma: A lightweight social networking server # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.CounterCache do alias Pleroma.CounterCache alias Pleroma.Repo use Ecto.Schema import Ecto.Changeset import Ecto.Query schema "counter_cache" do field(:instance, :string) field(:public, :integer) field(:unlisted, :integer) field(:private, :integer) field(:direct, :integer) end def changeset(struct, params) do struct |> cast(params, [:instance, :public, :unlisted, :private, :direct]) |> validate_required([:instance]) |> unique_constraint(:instance) end def get_by_instance(instance) do CounterCache |> select([c], %{ "public" => c.public, "unlisted" => c.unlisted, "private" => c.private, "direct" => c.direct }) |> where([c], c.instance == ^instance) |> Repo.one() |> case do nil -> %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0} val -> val end end def get_sum do CounterCache |> select([c], %{ "public" => type(sum(c.public), :integer), "unlisted" => type(sum(c.unlisted), :integer), "private" => type(sum(c.private), :integer), "direct" => type(sum(c.direct), :integer) }) |> Repo.one() end def set(instance, values) do params = Enum.reduce( ["public", "private", "unlisted", "direct"], %{"instance" => instance}, fn param, acc -> Map.put_new(acc, param, Map.get(values, param, 0)) end ) %CounterCache{} |> changeset(params) |> Repo.insert( on_conflict: [ set: [ public: params["public"], private: params["private"], unlisted: params["unlisted"], direct: params["direct"] ] ], returning: true, conflict_target: :instance ) end end