mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-12 01:13:10 -06:00
Change the way the memberships are saved in the client API database
This commit is contained in:
parent
3ba3cf606f
commit
95f81d0d24
|
|
@ -30,6 +30,11 @@ CREATE TABLE IF NOT EXISTS memberships (
|
||||||
room_id TEXT NOT NULL,
|
room_id TEXT NOT NULL,
|
||||||
-- The ID of the join membership event
|
-- The ID of the join membership event
|
||||||
event_id TEXT NOT NULL,
|
event_id TEXT NOT NULL,
|
||||||
|
-- Is the user still in the room? We use a boolean instead of just deleting
|
||||||
|
-- the row to know if the user has been in the room at some point
|
||||||
|
-- If set to false, event_id would be the event ID of the leave/kick/ban
|
||||||
|
-- membership event
|
||||||
|
still_in_room BOOLEAN NOT NULL,
|
||||||
|
|
||||||
-- A user can only be member of a room once
|
-- A user can only be member of a room once
|
||||||
PRIMARY KEY (localpart, room_id)
|
PRIMARY KEY (localpart, room_id)
|
||||||
|
|
@ -40,24 +45,26 @@ CREATE UNIQUE INDEX IF NOT EXISTS membership_event_id ON memberships(event_id);
|
||||||
`
|
`
|
||||||
|
|
||||||
const insertMembershipSQL = `
|
const insertMembershipSQL = `
|
||||||
INSERT INTO memberships(localpart, room_id, event_id) VALUES ($1, $2, $3)
|
INSERT INTO memberships(localpart, room_id, event_id, still_in_room)
|
||||||
ON CONFLICT (localpart, room_id) DO UPDATE SET event_id = EXCLUDED.event_id
|
VALUES ($1, $2, $3, $4)
|
||||||
|
ON CONFLICT (localpart, room_id) DO
|
||||||
|
UPDATE SET event_id = EXCLUDED.event_id, still_in_room = EXCLUDED.still_in_room
|
||||||
`
|
`
|
||||||
|
|
||||||
const selectMembershipSQL = "" +
|
const selectMembershipSQL = "" +
|
||||||
"SELECT * from memberships WHERE localpart = $1 AND room_id = $2"
|
"SELECT * from memberships WHERE localpart = $1 AND room_id = $2"
|
||||||
|
|
||||||
const selectMembershipsByLocalpartSQL = "" +
|
const selectMembershipsByLocalpartSQL = "" +
|
||||||
"SELECT room_id, event_id FROM memberships WHERE localpart = $1"
|
"SELECT room_id, event_id FROM memberships WHERE localpart = $1 AND still_in_room = true"
|
||||||
|
|
||||||
const selectMembershipsByRoomIDSQL = "" +
|
const selectMembershipsByRoomIDSQL = "" +
|
||||||
"SELECT localpart, event_id FROM memberships WHERE room_id = $1"
|
"SELECT localpart, event_id FROM memberships WHERE room_id = $1 AND still_in_room = true"
|
||||||
|
|
||||||
const deleteMembershipsByEventIDsSQL = "" +
|
const deleteMembershipsByEventIDsSQL = "" +
|
||||||
"DELETE FROM memberships WHERE event_id = ANY($1)"
|
"DELETE FROM memberships WHERE event_id = ANY($1)"
|
||||||
|
|
||||||
const updateMembershipByEventIDSQL = "" +
|
const updateMembershipByEventIDSQL = "" +
|
||||||
"UPDATE memberships SET event_id = $2 WHERE event_id = $1"
|
"UPDATE memberships SET event_id = $2, still_in_room = $3 WHERE event_id = $1"
|
||||||
|
|
||||||
type membershipStatements struct {
|
type membershipStatements struct {
|
||||||
deleteMembershipsByEventIDsStmt *sql.Stmt
|
deleteMembershipsByEventIDsStmt *sql.Stmt
|
||||||
|
|
@ -91,8 +98,8 @@ func (s *membershipStatements) prepare(db *sql.DB) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *membershipStatements) insertMembership(localpart string, roomID string, eventID string, txn *sql.Tx) (err error) {
|
func (s *membershipStatements) insertMembership(localpart string, roomID string, eventID string, stillInRoom bool, txn *sql.Tx) (err error) {
|
||||||
_, err = txn.Stmt(s.insertMembershipStmt).Exec(localpart, roomID, eventID)
|
_, err = txn.Stmt(s.insertMembershipStmt).Exec(localpart, roomID, eventID, stillInRoom)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,11 +121,12 @@ func (d *Database) SetPartitionOffset(topic string, partition int32, offset int6
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveMembership saves the user matching a given localpart as a member of a given
|
// SaveMembership saves the user matching a given localpart as a member of a given
|
||||||
// room. It also stores the ID of the `join` membership event.
|
// room. It also stores the ID of the membership event and a flag on whether the user
|
||||||
|
// is still in the room.
|
||||||
// If a membership already exists between the user and the room, or of the
|
// If a membership already exists between the user and the room, or of the
|
||||||
// insert fails, returns the SQL error
|
// insert fails, returns the SQL error
|
||||||
func (d *Database) SaveMembership(localpart string, roomID string, eventID string, txn *sql.Tx) error {
|
func (d *Database) SaveMembership(localpart string, roomID string, eventID string, stillInRoom bool, txn *sql.Tx) error {
|
||||||
return d.memberships.insertMembership(localpart, roomID, eventID, txn)
|
return d.memberships.insertMembership(localpart, roomID, eventID, stillInRoom, txn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeMembershipsByEventIDs removes the memberships of which the `join` membership
|
// removeMembershipsByEventIDs removes the memberships of which the `join` membership
|
||||||
|
|
@ -135,9 +136,9 @@ func (d *Database) removeMembershipsByEventIDs(eventIDs []string, txn *sql.Tx) e
|
||||||
return d.memberships.deleteMembershipsByEventIDs(eventIDs, txn)
|
return d.memberships.deleteMembershipsByEventIDs(eventIDs, txn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMemberships adds the "join" membership events included in a given state
|
// UpdateMemberships saves the membership events included in a given state events
|
||||||
// events array, and removes those which ID is included in a given array of events
|
// array, and removes those which ID is included in a given array of events IDs.
|
||||||
// IDs. All of the process is run in a transaction, which commits only once/if every
|
// All of the process is run in a transaction, which commits only once/if every
|
||||||
// insertion and deletion has been successfully processed.
|
// insertion and deletion has been successfully processed.
|
||||||
// Returns a SQL error if there was an issue with any part of the process
|
// Returns a SQL error if there was an issue with any part of the process
|
||||||
func (d *Database) UpdateMemberships(eventsToAdd []gomatrixserverlib.Event, idsToRemove []string) error {
|
func (d *Database) UpdateMemberships(eventsToAdd []gomatrixserverlib.Event, idsToRemove []string) error {
|
||||||
|
|
@ -179,8 +180,11 @@ func (d *Database) UpdateMembership(oldEventID string, newEventID string) error
|
||||||
return d.memberships.updateMembershipByEventID(oldEventID, newEventID)
|
return d.memberships.updateMembershipByEventID(oldEventID, newEventID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newMembership will save a new membership in the database if the given state
|
// newMembership will save a new membership in the database, with a flag on whether
|
||||||
// event is a "join" membership event
|
// the user is still in the room. This flag is set to true if the given state
|
||||||
|
// event is a "join" membership event and false if the event is a "leave" or "ban"
|
||||||
|
// membership. If the event isn't a m.room.member event with one of these three
|
||||||
|
// values, does nothing.
|
||||||
// If the event isn't a "join" membership event, does nothing
|
// If the event isn't a "join" membership event, does nothing
|
||||||
// If an error occurred, returns it
|
// If an error occurred, returns it
|
||||||
func (d *Database) newMembership(ev gomatrixserverlib.Event, txn *sql.Tx) error {
|
func (d *Database) newMembership(ev gomatrixserverlib.Event, txn *sql.Tx) error {
|
||||||
|
|
@ -204,7 +208,13 @@ func (d *Database) newMembership(ev gomatrixserverlib.Event, txn *sql.Tx) error
|
||||||
|
|
||||||
// Only "join" membership events can be considered as new memberships
|
// Only "join" membership events can be considered as new memberships
|
||||||
if membership == "join" {
|
if membership == "join" {
|
||||||
if err := d.SaveMembership(localpart, roomID, eventID, txn); err != nil {
|
if err := d.SaveMembership(localpart, roomID, eventID, true, txn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if membership == "leave" || membership == "ban" {
|
||||||
|
// If the user left the room, save the new event ID and mark them as
|
||||||
|
// not in the room anymore
|
||||||
|
if err := d.SaveMembership(localpart, roomID, eventID, false, txn); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,8 @@ func GetMemberships(
|
||||||
req *http.Request, roomID string, accountDB *accounts.Database,
|
req *http.Request, roomID string, accountDB *accounts.Database,
|
||||||
queryAPI api.RoomserverQueryAPI,
|
queryAPI api.RoomserverQueryAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
// TODO: Check if the user is or has been in the room, and respond with
|
// TODO: If the user has been in the room before but isn't
|
||||||
// M_FORBIDDEN if not. If the user has been in the room before but isn't
|
// anymore, only send the members list as it was before they left.
|
||||||
// anymore, send the members list as it was before they left.
|
|
||||||
|
|
||||||
memberships, err := accountDB.GetMembershipsByRoomID(roomID)
|
memberships, err := accountDB.GetMembershipsByRoomID(roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue