Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85628461
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/marker.ex b/lib/pleroma/marker.ex
index 4b8198690..098fe3bbd 100644
--- a/lib/pleroma/marker.ex
+++ b/lib/pleroma/marker.ex
@@ -1,111 +1,112 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Marker do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias Ecto.Multi
alias Pleroma.Repo
alias Pleroma.User
alias __MODULE__
@timelines ["notifications"]
schema "markers" do
field(:last_read_id, :string, default: "")
field(:timeline, :string, default: "")
field(:lock_version, :integer, default: 0)
field(:unread_count, :integer, default: 0)
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
timestamps()
end
def get_markers(user, timelines \\ []) do
Repo.all(get_query(user, timelines))
end
def upsert(%User{} = user, attrs) do
attrs
|> Map.take(@timelines)
|> Enum.reduce(Multi.new(), fn {timeline, timeline_attrs}, multi ->
marker =
user
|> get_marker(timeline)
|> changeset(timeline_attrs)
Multi.insert(multi, timeline, marker,
returning: true,
on_conflict: {:replace, [:last_read_id, :unread_count]},
conflict_target: [:user_id, :timeline]
)
end)
|> Repo.transaction()
end
@spec multi_set_unread_count(Multi.t(), User.t(), String.t()) :: Multi.t()
def multi_set_unread_count(multi, %User{} = user, "notifications") do
multi
|> Multi.run(:counters, fn _repo, _changes ->
query =
from(q in Pleroma.Notification,
where: q.user_id == ^user.id,
select: %{
timeline: "notifications",
- user_id: ^user.id,
- unread_count: fragment("SUM( CASE WHEN seen = false THEN 1 ELSE 0 END ) as unread_count")
+ user_id: type(^user.id, :string),
+ unread_count: fragment("SUM( CASE WHEN seen = false THEN 1 ELSE 0 END )"),
+ last_read_id: type(fragment("MAX( CASE WHEN seen = true THEN id ELSE null END )"), :string)
}
)
{:ok, Repo.one(query)}
end)
|> Multi.insert(
:marker,
fn %{counters: attrs} ->
Marker
|> struct(attrs)
|> Ecto.Changeset.change()
end,
returning: true,
on_conflict: {:replace, [:last_read_id, :unread_count]},
conflict_target: [:user_id, :timeline]
)
end
def set_unread_count(%User{} = user, timeline) do
Multi.new()
|> multi_set_unread_count(user, timeline)
|> Repo.transaction()
end
defp get_marker(user, timeline) do
case Repo.find_resource(get_query(user, timeline)) do
{:ok, marker} -> %__MODULE__{marker | user: user}
_ -> %__MODULE__{timeline: timeline, user_id: user.id}
end
end
@doc false
defp changeset(marker, attrs) do
marker
|> cast(attrs, [:last_read_id, :unread_count])
|> validate_required([:user_id, :timeline, :last_read_id])
|> validate_inclusion(:timeline, @timelines)
end
defp by_timeline(query, timeline) do
from(m in query, where: m.timeline in ^List.wrap(timeline))
end
defp by_user_id(query, id), do: from(m in query, where: m.user_id == ^id)
defp get_query(user, timelines) do
__MODULE__
|> by_user_id(user.id)
|> by_timeline(timelines)
end
end
diff --git a/priv/repo/migrations/20191021113356_add_unread_to_marker.exs b/priv/repo/migrations/20191021113356_add_unread_to_marker.exs
index 32789b7f9..964c7fb98 100644
--- a/priv/repo/migrations/20191021113356_add_unread_to_marker.exs
+++ b/priv/repo/migrations/20191021113356_add_unread_to_marker.exs
@@ -1,49 +1,45 @@
defmodule Pleroma.Repo.Migrations.AddUnreadToMarker do
use Ecto.Migration
import Ecto.Query
alias Pleroma.Repo
alias Pleroma.Notification
def up do
alter table(:markers) do
add_if_not_exists(:unread_count, :integer, default: 0)
end
flush()
update_markers()
end
def down do
alter table(:markers) do
remove_if_exists(:unread_count, :integer)
end
end
def update_markers do
from(q in Notification,
select: %{
timeline: "notifications",
user_id: q.user_id,
- unread_count: fragment("COUNT(*) FILTER (WHERE seen = false) as unread_count"),
- last_read_id: fragment("(MAX(id) FILTER (WHERE seen = true)::text) as last_read_id ")
+ unread_count: fragment("SUM( CASE WHEN seen = false THEN 1 ELSE 0 END )"),
+ last_read_id: type(fragment("MAX( CASE WHEN seen = true THEN id ELSE null END )"), :string)
},
group_by: [q.user_id]
)
|> Repo.all()
- |> Enum.reduce(Ecto.Multi.new(), fn attrs, multi ->
- marker =
- Pleroma.Marker
- |> struct(attrs)
- |> Ecto.Changeset.change()
-
- multi
- |> Ecto.Multi.insert(attrs[:user_id], marker,
+ |> Enum.each(fn attrs ->
+ Pleroma.Marker
+ |> struct(attrs)
+ |> Ecto.Changeset.change()
+ |> Pleroma.Repo.insert(
returning: true,
on_conflict: {:replace, [:last_read_id, :unread_count]},
conflict_target: [:user_id, :timeline]
)
end)
- |> Pleroma.Repo.transaction()
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Aug 8, 12:35 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1723325
Default Alt Text
(5 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment