total rebase
[anni] / lib / pleroma / counter_cache.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.CounterCache do
6   alias Pleroma.CounterCache
7   alias Pleroma.Repo
8   use Ecto.Schema
9   import Ecto.Changeset
10   import Ecto.Query
11
12   schema "counter_cache" do
13     field(:instance, :string)
14     field(:public, :integer)
15     field(:unlisted, :integer)
16     field(:private, :integer)
17     field(:direct, :integer)
18   end
19
20   def changeset(struct, params) do
21     struct
22     |> cast(params, [:instance, :public, :unlisted, :private, :direct])
23     |> validate_required([:instance])
24     |> unique_constraint(:instance)
25   end
26
27   def get_by_instance(instance) do
28     CounterCache
29     |> select([c], %{
30       "public" => c.public,
31       "unlisted" => c.unlisted,
32       "private" => c.private,
33       "direct" => c.direct
34     })
35     |> where([c], c.instance == ^instance)
36     |> Repo.one()
37     |> case do
38       nil -> %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0}
39       val -> val
40     end
41   end
42
43   def get_sum do
44     CounterCache
45     |> select([c], %{
46       "public" => type(sum(c.public), :integer),
47       "unlisted" => type(sum(c.unlisted), :integer),
48       "private" => type(sum(c.private), :integer),
49       "direct" => type(sum(c.direct), :integer)
50     })
51     |> Repo.one()
52   end
53
54   def set(instance, values) do
55     params =
56       Enum.reduce(
57         ["public", "private", "unlisted", "direct"],
58         %{"instance" => instance},
59         fn param, acc ->
60           Map.put_new(acc, param, Map.get(values, param, 0))
61         end
62       )
63
64     %CounterCache{}
65     |> changeset(params)
66     |> Repo.insert(
67       on_conflict: [
68         set: [
69           public: params["public"],
70           private: params["private"],
71           unlisted: params["unlisted"],
72           direct: params["direct"]
73         ]
74       ],
75       returning: true,
76       conflict_target: :instance
77     )
78   end
79 end