Add membership table

This commit is contained in:
Pim Kunis 2021-09-08 12:03:41 +02:00
parent a682f1c7ad
commit 46b4199618
4 changed files with 63 additions and 6 deletions

View file

@ -21,7 +21,8 @@ defmodule Architex.RoomServer do
Account, Account,
JoinedRoom, JoinedRoom,
Device, Device,
DeviceTransaction DeviceTransaction,
Membership
} }
alias Architex.StateResolution.Authorization alias Architex.StateResolution.Authorization
@ -607,6 +608,7 @@ defmodule Architex.RoomServer do
state_set = StateResolution.resolve_forward_extremities(event) state_set = StateResolution.resolve_forward_extremities(event)
# TODO: Do this as a background job, and not after every insert... # TODO: Do this as a background job, and not after every insert...
_ = update_joined_rooms(room, state_set) _ = update_joined_rooms(room, state_set)
:ok = update_membership(room, state_set)
{:ok, state_set, room, event} {:ok, state_set, room, event}
else else
@ -651,4 +653,34 @@ defmodule Architex.RoomServer do
where: jr.room_id == ^room_id and a.localpart in ^not_joined_localparts where: jr.room_id == ^room_id and a.localpart in ^not_joined_localparts
) )
end end
# TODO: Might be better to calculate membership changes...
@spec update_membership(Room.t(), t()) :: :ok
defp update_membership(%Room{id: room_id}, state_set) do
server_name = Architex.server_name()
state_set
|> Enum.filter(fn {{type, state_key}, _} ->
type == "m.room.member" and Architex.get_domain(state_key) == server_name
end)
|> Enum.group_by(
fn {_, %Event{content: %{"membership" => membership}}} ->
membership
end,
fn {{_, state_key}, _} ->
Architex.get_localpart(state_key)
end
)
|> Enum.each(fn {membership, localparts} ->
Repo.insert_all(
Membership,
from(a in Account,
where: a.localpart in ^localparts,
select: %{account_id: a.id, room_id: ^room_id, membership: ^membership}
),
on_conflict: {:replace, [:membership]},
conflict_target: [:account_id, :room_id]
)
end)
end
end end

View file

@ -0,0 +1,18 @@
defmodule Architex.Membership do
use Ecto.Schema
alias Architex.{Account, Room}
@type t :: %__MODULE__{
account_id: integer(),
room_id: String.t(),
membership: String.t()
}
@primary_key false
schema "membership" do
belongs_to :account, Account, primary_key: true
belongs_to :room, Room, primary_key: true, type: :string
field :membership, :string
end
end

View file

@ -47,11 +47,12 @@ defmodule ArchitexWeb.Client.SyncController do
{room_id, joined_room} {room_id, joined_room}
end) end)
next_batch = Enum.map(events_per_room, fn {_, events} -> next_batch =
%Event{nid: last_nid} = List.last(events) Enum.map(events_per_room, fn {_, events} ->
last_nid %Event{nid: last_nid} = List.last(events)
end) last_nid
|> Enum.max(fn -> 0 end) end)
|> Enum.max(fn -> 0 end)
data = %{ data = %{
next_batch: Integer.to_string(next_batch), next_batch: Integer.to_string(next_batch),

View file

@ -91,5 +91,11 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
add :event_id, :string, null: false add :event_id, :string, null: false
end end
create table(:membership, primary_key: false) do
add :account_id, references(:accounts), primary_key: true
add :room_id, references(:rooms, type: :string), primary_key: true
add :membership, :string, null: false
end
end end
end end