Merge remote-tracking branch 'origin/develop' into manifest
[akkoma] / lib / pleroma / counter_cache.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 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