Remove filtering on /members and implement /joined_members

This commit is contained in:
Brendan Abolivier 2017-08-24 15:34:28 +01:00
parent 81e454c0ba
commit f946702dd5
No known key found for this signature in database
GPG key ID: 8EF1500759F70623
6 changed files with 36 additions and 19 deletions

View file

@ -33,11 +33,12 @@ type response struct {
// GetMemberships implements GET /rooms/{roomId}/members // GetMemberships implements GET /rooms/{roomId}/members
func GetMemberships( func GetMemberships(
req *http.Request, device *authtypes.Device, roomID string, req *http.Request, device *authtypes.Device, roomID string, joinedOnly bool,
accountDB *accounts.Database, cfg config.Dendrite, accountDB *accounts.Database, cfg config.Dendrite,
queryAPI api.RoomserverQueryAPI, queryAPI api.RoomserverQueryAPI,
) util.JSONResponse { ) util.JSONResponse {
queryReq := api.QueryMembershipsForRoomRequest{ queryReq := api.QueryMembershipsForRoomRequest{
JoinedOnly: joinedOnly,
RoomID: roomID, RoomID: roomID,
Sender: device.UserID, Sender: device.UserID,
} }

View file

@ -302,7 +302,14 @@ func Setup(
r0mux.Handle("/rooms/{roomID}/members", r0mux.Handle("/rooms/{roomID}/members",
common.MakeAuthAPI("rooms_members", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { common.MakeAuthAPI("rooms_members", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return readers.GetMemberships(req, device, vars["roomID"], accountDB, cfg, queryAPI) return readers.GetMemberships(req, device, vars["roomID"], false, accountDB, cfg, queryAPI)
}),
)
r0mux.Handle("/rooms/{roomID}/joined_members",
common.MakeAuthAPI("rooms_members", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars := mux.Vars(req)
return readers.GetMemberships(req, device, vars["roomID"], true, accountDB, cfg, queryAPI)
}), }),
) )

View file

@ -102,6 +102,8 @@ type QueryEventsByIDResponse struct {
// QueryMembershipsForRoomRequest is a request to QueryMembershipsForRoom // QueryMembershipsForRoomRequest is a request to QueryMembershipsForRoom
type QueryMembershipsForRoomRequest struct { type QueryMembershipsForRoomRequest struct {
// If true, only returns the membership events of "join" membership
JoinedOnly bool `json:"joined_only"`
// ID of the room to fetch memberships from // ID of the room to fetch memberships from
RoomID string `json:"room_id"` RoomID string `json:"room_id"`
// ID of the user sending the request // ID of the user sending the request

View file

@ -49,10 +49,11 @@ type RoomserverQueryAPIDatabase interface {
// false if not. // false if not.
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
GetMembership(roomNID types.RoomNID, requestSenderUserID string) (membershipEventNID types.EventNID, stillInRoom bool, err error) GetMembership(roomNID types.RoomNID, requestSenderUserID string) (membershipEventNID types.EventNID, stillInRoom bool, err error)
// Lookup the "join" membership event numeric IDs for all user that are // Lookup the membership event numeric IDs for all user that are or have
// currently members of a given room. // been members of a given room. Only lookup events of "join" membership if
// joinOnly is set to true.
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
GetJoinMembershipEventNIDsForRoom(roomNID types.RoomNID) ([]types.EventNID, error) GetMembershipEventNIDsForRoom(roomNID types.RoomNID, joinOnly bool) ([]types.EventNID, error)
// Look up the active invites targeting a user in a room and return the // Look up the active invites targeting a user in a room and return the
// numeric state key IDs for the user IDs who sent them. // numeric state key IDs for the user IDs who sent them.
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
@ -217,14 +218,14 @@ func (r *RoomserverQueryAPI) QueryMembershipsForRoom(
var events []types.Event var events []types.Event
if stillInRoom { if stillInRoom {
var eventNIDs []types.EventNID var eventNIDs []types.EventNID
eventNIDs, err = r.DB.GetJoinMembershipEventNIDsForRoom(roomNID) eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(roomNID, request.JoinedOnly)
if err != nil { if err != nil {
return err return err
} }
events, err = r.DB.Events(eventNIDs) events, err = r.DB.Events(eventNIDs)
} else { } else {
events, err = r.getMembershipsBeforeEventNID(membershipEventNID) events, err = r.getMembershipsBeforeEventNID(membershipEventNID, request.JoinedOnly)
} }
if err != nil { if err != nil {
@ -243,7 +244,7 @@ func (r *RoomserverQueryAPI) QueryMembershipsForRoom(
// of the event's room as it was when this event was fired, then filters the state events to // of the event's room as it was when this event was fired, then filters the state events to
// only keep the "m.room.member" events with a "join" membership. These events are returned. // only keep the "m.room.member" events with a "join" membership. These events are returned.
// Returns an error if there was an issue fetching the events. // Returns an error if there was an issue fetching the events.
func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(eventNID types.EventNID) ([]types.Event, error) { func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(eventNID types.EventNID, joinedOnly bool) ([]types.Event, error) {
events := []types.Event{} events := []types.Event{}
// Lookup the event NID // Lookup the event NID
eIDs, err := r.DB.EventIDs([]types.EventNID{eventNID}) eIDs, err := r.DB.EventIDs([]types.EventNID{eventNID})
@ -277,6 +278,10 @@ func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(eventNID types.EventNI
return nil, err return nil, err
} }
if !joinedOnly {
return stateEvents, nil
}
// Filter the events to only keep the "join" membership events // Filter the events to only keep the "join" membership events
for _, event := range stateEvents { for _, event := range stateEvents {
membership, err := event.Membership() membership, err := event.Membership()

View file

@ -77,7 +77,7 @@ const selectMembershipsFromRoomAndMembershipSQL = "" +
" WHERE room_nid = $1 AND membership_nid = $2" " WHERE room_nid = $1 AND membership_nid = $2"
const selectMembershipsFromRoomSQL = "" + const selectMembershipsFromRoomSQL = "" +
"SELECT membership_nid, event_nid FROM roomserver_membership" + "SELECT event_nid FROM roomserver_membership" +
" WHERE room_nid = $1" " WHERE room_nid = $1"
const selectMembershipForUpdateSQL = "" + const selectMembershipForUpdateSQL = "" +
@ -140,20 +140,18 @@ func (s *membershipStatements) selectMembershipFromRoomAndTarget(
func (s *membershipStatements) selectMembershipsFromRoom( func (s *membershipStatements) selectMembershipsFromRoom(
roomNID types.RoomNID, roomNID types.RoomNID,
) (eventNIDs map[types.EventNID]membershipState, err error) { ) (eventNIDs []types.EventNID, err error) {
rows, err := s.selectMembershipsFromRoomStmt.Query(roomNID) rows, err := s.selectMembershipsFromRoomStmt.Query(roomNID)
if err != nil { if err != nil {
return return
} }
eventNIDs = make(map[types.EventNID]membershipState)
for rows.Next() { for rows.Next() {
var eNID types.EventNID var eNID types.EventNID
var membership membershipState if err = rows.Scan(&eNID); err != nil {
if err = rows.Scan(&membership, &eNID); err != nil {
return return
} }
eventNIDs[eNID] = membership eventNIDs = append(eventNIDs, eNID)
} }
return return
} }

View file

@ -576,11 +576,15 @@ func (d *Database) GetMembership(roomNID types.RoomNID, requestSenderUserID stri
return senderMembershipEventNID, senderMembership == membershipStateJoin, nil return senderMembershipEventNID, senderMembership == membershipStateJoin, nil
} }
// GetJoinMembershipEventNIDsForRoom implements query.RoomserverQueryAPIDB // GetMembershipEventNIDsForRoom implements query.RoomserverQueryAPIDB
func (d *Database) GetJoinMembershipEventNIDsForRoom(roomNID types.RoomNID) ([]types.EventNID, error) { func (d *Database) GetMembershipEventNIDsForRoom(roomNID types.RoomNID, joinOnly bool) ([]types.EventNID, error) {
if joinOnly {
return d.statements.selectMembershipsFromRoomAndMembership(roomNID, membershipStateJoin) return d.statements.selectMembershipsFromRoomAndMembership(roomNID, membershipStateJoin)
} }
return d.statements.selectMembershipsFromRoom(roomNID)
}
type transaction struct { type transaction struct {
txn *sql.Tx txn *sql.Tx
} }