a940b5e50cca97ef1605a5d81014888256b7f143
[akkoma] / lib / pleroma / counter_cache.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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" => sum(c.public),
47 "unlisted" => sum(c.unlisted),
48 "private" => sum(c.private),
49 "direct" => sum(c.direct)
50 })
51 |> Repo.one()
52 |> Enum.map(fn {visibility, dec_count} ->
53 {visibility, Decimal.to_integer(dec_count)}
54 end)
55 |> Enum.into(%{})
56 end
57
58 def set(instance, values) do
59 params =
60 Enum.reduce(
61 ["public", "private", "unlisted", "direct"],
62 %{"instance" => instance},
63 fn param, acc ->
64 Map.put_new(acc, param, Map.get(values, param, 0))
65 end
66 )
67
68 %CounterCache{}
69 |> changeset(params)
70 |> Repo.insert(
71 on_conflict: [
72 set: [
73 public: params["public"],
74 private: params["private"],
75 unlisted: params["unlisted"],
76 direct: params["direct"]
77 ]
78 ],
79 returning: true,
80 conflict_target: :instance
81 )
82 end
83 end